2

我有编译为 x86 的 ac# 应用程序,因此它在 Windows 7 x64 上作为 32 位应用程序运行。在应用程序运行时,我需要检测活动窗口的可执行文件名。在 Winodws XP 上,以下代码运行良好(从活动窗口句柄获取进程文件名)。在 x64 上,它只报告 32 位进程的名称(为其他进程返回垃圾,可能是因为我没有检查返回的数据)。我正在传递使用 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;
    }

我可以在 64 位环境中从 32 位进程中获取该信息吗?谢谢。安德烈亚

4

2 回答 2

1

仅供参考,有一个 API GetWindowModuleFileName可以在一次调用中完成您想要的所有操作。不过,我还没有检查它是否在您的场景中效果更好。

于 2009-11-03T15:27:23.123 回答
1

由于没有错误检查:您是否单步执行了代码并验证了各种 API 调用,然后才GetModuleFileNameEx返回合理的信息?此外,您应该定义一些符号常量,而不是硬编码1040访问说明符。

你试过使用System.Diagnostics.Process.GetProcessById()吗?它有一个MainModule属性,您可以从中获取FileName。不过,值得一试。

不过,一些粗略的谷歌搜索表明您可能会陷入 x64 与 WoW64 的墙。这些更有用的搜索结果之一是-摘要:查看QueryFullProcessImageName

编辑:

显然,WMI 可以弥补 WoW64 的差距,让您可以做到SELECT ExecutablePath FROM Win32_Process WHERE ProcessID = %ProcessID%. 根据我的经验,WMI 有点重,所以它是最后的手段。

于 2010-09-22T08:35:41.463 回答