如何确定.NET应用程序是32位还是64位?

52

我有一个.NET应用程序,原本应该只编译为32位应用程序。我怀疑我的构建服务器实际上并没有这样做。

我该如何确定一个.NET应用程序是否真正设置为以32位模式运行?


你的问题不是很清楚 - 你想检查一个dll文件还是想检查一个应用程序? - Jaco Pretorius
@jaco - 这并不重要。exe文件也是一种汇编文件。他的主要观点是需要在外部完成,因为生成的程序是构建服务器的结果。 - x0n
没错,但我正在努力弄清他在看什么。但你说得对,这不应该有影响。 - Jaco Pretorius
8个回答

58
如果您想检查一个正在运行的应用程序是以32位还是64位模式运行的,请打开任务管理器并检查进程名称旁边是否有星号(*32)。
编辑(从manna的答案中导入):在Win8.1中,进程的“位数”列在一个单独的详细信息列中标记为“平台”。 (右键单击任何列标题以显示“选择列”菜单。)
如果您有一个已编译的dll,并且您想检查它是否以32位或64位模式编译,请执行以下操作(来自related question)。我认为您希望将dll编译为AnyCPU
打开Visual Studio命令提示符并键入“corflags [your assembly]”。您将得到类似于以下内容:
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC>corflags "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll" Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8 Copyright (c) Microsoft Corporation. All rights reserved. Version : v2.0.50727 CLR Header: 2.5 PE : PE32 CorFlags : 24 ILONLY : 0 32BIT : 0 Signed : 1
您要查看的是PE和32BIT
AnyCpu:

PE: PE32
32位: 0

x86:

PE: PE32
32位: 1

x64:

PE: PE32+
32位: 0


1
谢谢,这正是我想要的。尽管你的答案让我有点恼火,因为我知道 CorFlags 可以更改设置,但文档中没有任何内容告诉我它也可以读取它。 - Jonathan Allen
2
顺便提一下,在VS 2017中它被称为“VS开发人员命令提示符”。(名称更改使其难以找到。) - jpmc26
corflags的指令和输出已经发生了变化。我不想编辑这个答案,所以我发布了一个新的:https://dev59.com/kG865IYBdhLWcg3wfuwk#73744268 - Florian Winter

28

在运行时进行如下操作...

您可以评估 IntPtr.Size。如果 IntPtr.Size == 4,则是32位(4 x 8)。如果 IntPtr.Size == 8,则是64位(8 x 8)。


1
那听起来像是运行时,而不是设计时。 - Steven Sudit
2
它仍然很有用;如果您想在运行时做出任何基于平台的决策。 - Najeeb
我已经测试过,在 UWP 应用程序中也可以工作。 - Tony

12

1
我认为这并没有回答楼主的问题。 - Will A
汇编中是否有某个标志,指示是将其JIT为32位、64位还是两者都可以? - Steven Sudit
1
@Will A:OP不能把那段代码放到他的应用程序中,在加载时显示一条消息(或其他什么东西)吗?这是一个诚实的问题——我真的认为这就是他想要的。现在我看到其他一些答案,意识到也许他想要的是进程外的东西。 - Dan Tao
@Jim:我认为sizeof(IntPtr)是不合法的。 - Dan Tao
@Jim:我错了:看起来只有在“不安全”的上下文中才是合法的。 - Dan Tao
显示剩余2条评论

7

最快的方法可能是在64位机器上运行时,在任务管理器中它的名称后面会有一个星号(*)。星号表示它正在syswow64中运行,因此被标记为32位。

另一种方法是运行corflags.exe并显示你想要的答案。这个工具随着.NET SDK一起提供。


1
同意,任务管理器始终是准确的。Corflags 只显示意图。 - Hans Passant

4
我使用以下代码:
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process(
    [In] IntPtr hProcess,
    [Out] out bool wow64Process
);

使用:

public static bool IsProcess64(Process process)
{
    if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6) {
        bool ret_val;

        try {
            if (!WindowsAPI.IsWow64Process(process.Handle,out ret_val)) ret_val = false;
        } catch {
            ret_val = false;
        }

        if (!ret_val && IntPtr.Size == 8) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

您可以将Process.CurrentProcess或类似的内容传递给它。

这段代码存在一些缺陷,主要与异常处理有关: "catch-all-and-everything" 子句也会捕获像 OutOfMemoryException、ThreadAbortException、AccessViolationException 等表示 CLR 处于错误状态并且与所讨论的进程不是 64 位系统上的 32 位进程(WOW64)无关的所有内容。然后,如果为没有权限或已经消失的进程调用 "Handle" 属性,它将抛出异常 - 它仍然可能是 32 位进程。最后,如果 IntPtr.Size 是 64,则该进程是 64 位 - 不再需要其他检查。 - Christian.K
这是真的,我很久没有更改过这段代码了。我应该真正解决所有这些问题。 - Lloyd

2

这是对2010年旧的被接受答案的更新:

  1. 打开Visual Studio。
  2. 进入“工具” --> “命令行” --> “开发人员命令提示符”。
  3. 运行corflags <path/to/your/exe_or_dll_file>

corflags的输出已更改,现在看起来像这样:

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x3
ILONLY    : 1
32BITREQ  : 1
32BITPREF : 0
Signed    : 0

要查找的行是32BITREQ,意思是“需要32位”。如果您使用 Any CPU 构建但链接到32位本机DLL,则将其设置为1。这意味着您的DLL或EXE实际上是“ 32位(仅限)”,例如,无法在64位IIS应用程序池中运行。
如果DLL是使用平台 x64 而不是任意CPU构建的,则输出可能如下:
Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32+
CorFlags  : 0x1
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 0

字符串PE+表示该DLL是为x64构建的。对于x86Any CPU,它是PE32


2

如果你想非编程方式测试一个程序集,可以使用 corflags.exe

>corflags.exe <assembly>

<listing of header information, among them the 32bit-ness>

2

我正在寻找同样的信息,我发现自从Windows 8.1以来,就不再有星号了。

你有一个任务管理器详细信息列名为“平台”。它的内容是“32位”或“64位”。


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