C# 通过句柄 (hWnd) 32 和 64 位获取路径/文件名

Ron*_*Ron 5 .net c# 64-bit filenames path

我得到了以下代码来通过句柄获取路径/文件名:

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowThreadProcessId(IntPtr handle, out uint processId);

    public static string GetProcessPath(IntPtr hwnd)
    {
        uint pid = 0;
        GetWindowThreadProcessId(hwnd, out pid);
        Process proc = Process.GetProcessById((int)pid);
        return proc.MainModule.FileName.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

它在 32 位上运行良好,但在 64 位中出现错误 >“仅部分 ReadProcessMemory 或 WriteProcessMemory 请求已完成。” 该项目被编译为 x86(平台目标 x86)。

我该如何解决?

~谢谢罗恩

Cod*_*ray 3

从您的问题来看,您当前已将程序编译为 32 位应用程序。但是,您尝试查询的进程(假设您在 64 位版本的 Windows 上运行)无疑是 64 位进程。这种事情是不允许的。尽管您可以在 64 位版本的 Windows 上运行 32 位应用程序,但它们在专用的 Windows on Windows (WOW64) 子系统下运行。这就是为什么您会收到Win32Exception“仅部分 ReadProcessMemory 或 WriteProcessMemory 请求已完成”的原因。我同意,如果您还不知道 Windows 如何管理 32 位和 64 位进程,那么这不是最具描述性的错误消息,但有了这些知识,它至少会更有意义。

解决方案是将您的应用程序编译为 64 位应用程序 (x64),或针对“任何 CPU”。之后一切都应该按预期进行。如果可能的话,我建议使用“Any CPU”,这将允许应用程序在 32 位操作系统上以 32 位模式运行,在 64 位操作系统上以 64 位模式运行。这确实是理想的情况,假设:

  1. 您已正确编写 P/Invoke 定义(即,IntPtr在适当的情况下使用 ,而不是Integer)。
  2. 您不依赖于编译为 32 位的第 3 方 DLL(您没有其源代码)。