如何确定 System.Diagnostics.Process 是32位还是64位?

8
我尝试过:
process.MainModule.FileName.Contains("x86")

但是对于一个x64进程,它抛出了一个异常:

Win32Exception: 只有ReadProcessMemory或WriteProcessMemory请求的一部分完成了


2
你问错了问题。真正的问题应该是:“我在ReadProcessMemory调用中哪里出了问题?” - Hans Passant
2
@Hans 只要问题标题得到回答,我对这个调用完全不在意。我列出的问题只是回答标题的一种方法。 - Jader Dias
可能是重复的问题:如何在程序中编程地知道一个进程是32位还是64位 - Jesse C. Slicer
@Jesse,你所指的问题是关于当前进程而不是另一个进程的。 - Jader Dias
请看我的回答。它考虑了其他进程,因为原帖不够清晰。 - Jesse C. Slicer
3个回答

12

您需要通过P/Invoke调用IsWow64Process函数:

[DllImport( "kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi )]
[return: MarshalAs( UnmanagedType.Bool )]
public static extern bool IsWow64Process( [In] IntPtr processHandle, [Out, MarshalAs( UnmanagedType.Bool )] out bool wow64Process );

这里有一个帮助方法可以让调用变得更容易:

public static bool Is64BitProcess( this Process process )
{
    if ( !Environment.Is64BitOperatingSystem )
        return false;

    bool isWow64Process;
    if ( !IsWow64Process( process.Handle, out isWow64Process ) )
        throw new Win32Exception( Marshal.GetLastWin32Error() );

    return !isWow64Process;
}

2
这种方法在32位Windows中会失败。 - Jader Dias
2
在32位Windows上,所有进程都是32位的,因此无需进行检查。我已经编辑了Is64BitProcess以反映这一点。 - Phil Devaney
使用Process.SafeHandle属性来防止在调用WinAPI时GC清理process.Handle。 - NN_

1

无论是 WMI 的 Win32_Process 还是 System.Diagnostics.Process,都没有提供任何明确的属性。

那么通过遍历已加载的模块 (Process.Modules) 如何呢?一个 32 位进程将会加载 %WinDir%\syswow64\kernel32.dll 而 64 位进程将会从 %WinDir%\system32\kernel32.dll 加载它(这是每一个 Windows 进程都会加载的 DLL)。

NB. 当然,这个测试在 x86 操作系统实例中会失败。


如果在32位进程中访问64位进程的模块,则会出现Win32Exception“32位进程无法访问64位进程的模块”,因此也会失败。 - tibx

1

Environment.Is64BitProcess 可能是你正在寻找的。


3
这只会告诉你调用程序是否为64位,我认为原帖想知道另一个进程是否为64位。 - Phil Devaney
1
@Phil:是的,我不确定原帖作者是什么意思。我觉得他可以投反对票或者发评论。 - Esteban Araya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接