Тема: AHK: Возвращение пути к PDF-файлу
Следующий код по клавише F11 выводит путь к файлу, открытому в PDF-просмотрщике. Но в случае, когда открыто несколько окон, путь определяется неверно. Как правильно получить путь для активного окна?
#SingleInstance Force
F11::
WinGet, PID, PID, A
obj := GetCommandLine2(PID, true, true)
;MsgBox, % "CommandLine = " obj.cmd "`nImagePath = " obj.path
MsgBox, % obj.cmd
Return
GetCommandLine2(PID, SetDebugPrivilege := false, GetImagePath := false) {
static SetDebug := 0, PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
if (SetDebugPrivilege && !SetDebug) {
if !res := SeDebugPrivilege()
SetDebug := 1
else {
MsgBox, 4, Ошибка SeDebugPrivilege(), Не удалось установить привилегии.`nОшибка %res%`nПродолжить?
IfMsgBox, No
Return
}
}
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
(A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
if (!A_Is64bitOS || IsWow64)
PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40
else
PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70
hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
if (A_PtrSize < PtrSize) { ; скрипт 32, целевой процесс 64
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64QueryInformationProcess64", Ptr)
failed := "NtWow64QueryInformationProcess64"
if !ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)
failed := "NtWow64ReadVirtualMemory64"
info := 0, szPBI := 48, offsetPEB := 8
}
else {
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtQueryInformationProcess", Ptr)
failed := "NtQueryInformationProcess"
ReadProcessMemory := "ReadProcessMemory"
if (A_PtrSize > PtrSize) ; скрипт 64, целевой процесс 32
info := 26, szPBI := 8, offsetPEB := 0
else ; скрипт и целевой процесс одной битности
info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
}
if failed {
DllCall("CloseHandle", Ptr, hProc)
MsgBox, Не удалось получить указатель на функцию %failed%
Return
}
VarSetCapacity(PBI, 48, 0)
if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS {
DllCall("CloseHandle", Ptr, hProc)
Return
}
pPEB := NumGet(&PBI + offsetPEB, PtrType)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD, UShortP, szCMD, PtrType, 2, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD + PtrSize, pPtr, pCMD, PtrType, PtrSize, UIntP, bytes)
VarSetCapacity(buff, szCMD, 0)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pCMD, Ptr, &buff, PtrType, szCMD, UIntP, bytes)
obj := { cmd: StrGet(&buff, "UTF-16") }
if (GetImagePath && obj.cmd) {
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD - PtrSize*2, UShortP, szPATH, PtrType, 2, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD - PtrSize, pPtr, pPATH, PtrType, PtrSize, UIntP, bytes)
VarSetCapacity(buff, szPATH, 0)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPATH, Ptr, &buff, PtrType, szPATH, UIntP, bytes)
obj.path := StrGet(&buff, "UTF-16") . (IsWow64 ? " *32" : "")
}
DllCall("CloseHandle", Ptr, hProc)
Return obj
}
SeDebugPrivilege() {
static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
NumPut(1, TOKEN_PRIVILEGES, "UInt")
NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
res := A_LastError
DllCall("CloseHandle", Ptr, token)
DllCall("CloseHandle", Ptr, hProc)
Return res ; в случае удачи 0
}