我有这个
function NazwaProcesu(const uchwyt: Thandle): string;
var
pid: DWORD;
hProcess: Thandle;
sciezka: array [0..MAX_PATH - 1] of char;
begin
GetWindowThreadProcessId(uchwyt, pid);
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pid);
if hProcess <> 0 then
try
GetModuleFileNameEx(hProcess, 0, sciezka, MAX_PATH)
finally
Result := sciezka;
CloseHandle(hProcess);
end;
end;
在Windows 7上32位没问题。在Win 8 x64上我有这个:
我认为最后3个条目应该是explorer.exe。谢谢你的帮助。
答案 0 :(得分:11)
据我所知,当在32位进程中执行代码时,此方法将无法检索64位进程信息。在WOW64模拟器中运行时,这种问题很常见,避免此类问题的最简单方法是在WOW64模拟器外部运行代码。也就是说,以64位进程运行代码。
解决此问题的其他可能方法,如果您无法重新编译为64位:
QueryFullProcessImageName
。我总是强调的另一点是错误检查很重要。致电GetModuleFileNameEx
时,您无法检查错误。调用显然是失败的,这就是为什么你最终得到一个未初始化的文本缓冲区。始终检查Windows API调用是否有错误。
答案 1 :(得分:3)
修改后:
function NazwaProcesu(const uchwyt: Thandle): string;
type
TQueryFullProcessImageName = function(hProcess: Thandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
pid: DWORD;
hProcess: Thandle;
sciezka: array [0 .. MAX_PATH - 1] of Char;
QueryFullProcessImageName: TQueryFullProcessImageName;
nSize: cardinal;
begin
Result := '';
GetWindowThreadProcessId(uchwyt, pid);
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pid);
if hProcess <> 0 then
try
if GetModuleFileNameEX(hProcess, 0, sciezka, MAX_PATH) <> 0 then Result := sciezka
else if Win32MajorVersion >= 6 then
begin
nSize := MAX_PATH;
ZeroMemory(@sciezka, MAX_PATH);
@QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
if Assigned(QueryFullProcessImageName) then
if QueryFullProcessImageName(hProcess, 0, sciezka, @nSize) then Result := sciezka
end;
finally
CloseHandle(hProcess);
end;
end;
答案 2 :(得分:0)
我最终寻求了一个完全不同的解决方法。关于PE标头的This answer提到了32位和64位Windows可执行文件中的PE标头。您可以完全绕开WinAPI检查,并通过在Binary模式下读取目标可执行文件并检查其是否与PE签名相匹配来检查目标可执行文件。
遗憾的是,在线上没有太多有关此问题的信息。我记得在某个论坛上看到过这个问题,该论坛被明确列为bug,但这大约是10年前。我希望当我们讨论这个问题时,更多的人意识到它。