开发者

Getting executable file name from handle in Windows x64

开发者 https://www.devze.com 2022-12-09 19:43 出处:网络
I have a c# application that is compiled as x86 so it runs as a 32bit application on Wi开发者_JS百科ndows 7 x64.

I have a c# application that is compiled as x86 so it runs as a 32bit application on Wi开发者_JS百科ndows 7 x64. While the application is running, I need to detect the executable name of the active window. On Winodws XP the following code worked fine (getting the process filename from the active window handle). On x64 it reports the name of only the 32bit processes (returning garbage for the others, probably because I'm not checking the data returned). I'm passing the handle of the active window that I got with the GetForegroundWindow API.

public static string GetProcessPathFromWindowHandle(IntPtr hWnd) {

        string filename = string.Empty;
        uint pid=0;
        Unmanaged.GetWindowThreadProcessId(hWnd, out pid);

        //error in Win64: returns strange characters for Win64 files
        const int nChars = 1024;
        StringBuilder filenameBuffer = new StringBuilder(nChars);
        IntPtr hProcess = Unmanaged.OpenProcess(1040, 0, pid);
        Unmanaged.GetModuleFileNameEx(hProcess, IntPtr.Zero, filenameBuffer, nChars);
        Unmanaged.CloseHandle(hProcess);

        filename = filenameBuffer.ToString();

        //Get the name of the Windows
        int length = Unmanaged.GetWindowTextLength(hWnd);
        StringBuilder sb = new StringBuilder(length + 1);
        Unmanaged.GetWindowText(hWnd, sb, sb.Capacity);

        Logger.Main.LogMessage("Window Title is: " + sb);
        Logger.Main.LogMessage("Process filename is: " + filename);
        return filename;
    }

Can I get that piece of information form a 32bit process in a 64bit environment? Thanks. Andrea


FYI, there's an API GetWindowModuleFileName that does all you want in a single call. I haven't checked if it works any better in your scenario though.


Since there's no error checking: have you stepped through the code and verified that the various API calls before GetModuleFileNameEx return sensible information? Also, you should define some symbolic constats instead of hardcoding the 1040 access specifier.

Have you tried using System.Diagnostics.Process.GetProcessById()? It has a MainModule property from where you can grab FileName. Worth a shot, though.

Some cursory googling indicates you might be running your head into x64 vs. WoW64 walls, though. One of those more useful search results was this - summary: check out QueryFullProcessImageName.

EDIT:

Apparently WMI can bridge the WoW64 gap, allowing you to do SELECT ExecutablePath FROM Win32_Process WHERE ProcessID = %ProcessID%. In my experience WMI is somewhat heavy, so it would be a last resort.

0

精彩评论

暂无评论...
验证码 换一张
取 消