为什么VB.Net检测到x86的操作系统架构,而C#检测到x64?

3

在同一台计算机上执行相同的代码会产生不同的输出:

VB 代码

Private Shared Function getOSPlatForm() As String
    Dim OsPlatForm As String = Nothing
    If IntPtr.Size * 8 = 32 Then
        OsPlatForm = "X86" 'win 32bit
    Else
        OsPlatForm = "X64" 'win 64bit
    End If
    Return OsPlatForm
End Function

这将输出x86。

C#代码

private static string getOSPlatForm()
{
    string OsPlatForm = null;
    if (IntPtr.Size * 8 == 32)
    {
        OsPlatForm = "X86";
        //win 32bit
    }
    else
    {
        OsPlatForm = "X64";
        //win 64bit
    }
    return OsPlatForm;
}

这段代码输出x64。
两个工程都使用相同的配置运行在AnyCPU上,我正在使用Visual Studio 2019。

running configuration


6
项目设置中有一个“prefer 32bit”选项。在两个项目中都查找一下。 - Ralf
2
额外的提示:有一个内置函数可用于检查 https://learn.microsoft.com/de-de/dotnet/api/system.environment.is64bitoperatingsystem?view=net-8.0 - Ralf
5
挑剔一点:你的测试检测到的是32位或64位进程,而不是处理器架构。在ARM / ARM64处理器上运行的进程仍将使用此测试报告“X86”或“X64”。如果您需要确定架构,那就是另外一回事了。 - madreflection
2
@Tudeschizieuinchid:你说得完全正确。我之前只是稍微提了一下,因为那不是问题的关键所在。 - madreflection
2
正如之前的评论者提到的,查看以下属性显示的内容:Environment.Is64BitOperatingEnvironment.Is64BitProcess。此外,如果使用 _AnyCPU_,请验证之前评论中提到的 Prefer 32-bit 的值。您还可以尝试特定编译为 x86 和 _x64_。 - Tu deschizi eu inchid
显示剩余8条评论
2个回答

0

在尝试使用winapi并得到相同奇怪结果后,我通过你们的帮助找到了解决方案。在VB.net中,下一行返回正确的架构

Environment.Is64BitOperatingSystem

因为

 <DllImport("kernel32.dll")>
        Shared Sub GetSystemInfo(ByRef lpSystemInfo As SYSTEM_INFO)
'does not return x64 system

请阅读这里的注释:GetNativeSystemInfo()IsWow64Process2() -- 此外,请查看 .NET 中 Is64BitOperatingSystem 的实现(不要忘记 #if WIN32)。 - Jimi

0

你的项目设置必须不同。

在这两种情况下,C#或VB.NET代码将且应该产生相同的结果。

唯一的区别是:

你默认运行vs2022,并使用“ANY CPU”。

这将导致一个x64位应用程序。

使用ANY CPU会导致一个x32位应用程序。

原因:

vs2022是Visual Studio的第一个x64位版本(是的,这些年来vs一直是一个x32位产品)。

所以,这意味着你现在真的需要密切关注给定项目使用的位大小设置。

就是这个设置:

enter image description here

如果您将vb.net和c#项目都设置为x86,则您的代码将产生相同的结果。(x32位)

如果您将vb.net项目和c#项目都设置为x64,则无论哪种情况下,您的代码都将产生相同的结果。

那么,在使用任何CPU时呢?

好吧,那么您得到的位数取决于如何启动项目以及由谁启动项目。

如果您启动命令行的x32位版本,则任何CPU都会产生x32位。

但是,如果您启动命令行的x64位版本,启动.exe程序,则会获得运行x64位的版本。

那么,包括Visual Studio启动程序(甚至使用F5)在内的任何进程例程都是哪种类型?

嗯,如果您使用vs2022(x64)或早期版本(x32),则在使用任何CPU时会得到不同的结果。

因此,在几乎所有情况下,如果您不关心,我建议使用任何CPU,因为我有一些类项目在一些桌面软件(x32)和一些基于Web的软件(x64)之间共享。但是,我实际上在x32位和x64位的项目中都包含了这些类项目的几个版本。

实际上,我强制构建所需的位大小(在基于Web的情况下 - 在我的情况下必须是x64位)。这是因为现在的Web服务器都以x64位运行,而且我在该项目中使用了一些非托管的.dll文件(非.net)。

最后一个问题?

如果您想确定位大小,确实可以使用IntPr.Size,但更常用和典型的方法内置于.net框架中。

因此,这个:(.net 4.0或更高版本)

        textBox1.Text = 
            System.Environment.Is64BitProcess ? "X64 but program" : "x32 bit program";

而且你还有其他几个不错的选择:

System.Environment.Is64BitOperatingSystem;

现在,大多数操作系统都是x64位的。但是,如果我们回到大约10年前,我们仍然会看到相当多的台式机 - 即使是来自OEM的也安装了x32位版本的Windows。

然而,如今你可以期望你的操作系统几乎总是x64位的。

强制将项目运行为x32位的唯一真正原因是当你处理未托管的代码时。

一些很好的例子:

Accounting packages: Sage 50, Sage300, QuickBooks and more?

它们目前都是基于x32位的产品。因此,如果您使用他们的SDK与这些会计软件进行接口交互,那么您必须强制您的.NET项目以x32位(x86设置)运行。
大多数办公自动化也是如此。Word、Excel、MS-Access甚至是MS-Access ODBC或OLEDB驱动程序?同样,您必须将.NET项目与您正在运行的Office的位大小匹配。
结果表明,在过去的一年中,Office现在开始默认为x64位,因此您现在必须将直接与Office接口的.NET项目设置为使用x64位,而即使在相对最近的过去,所有这类项目通常都必须以x32位运行。
因此,总结一下:
您的.NET和VB.NET项目应该产生相同的结果。不同结果的唯一原因是您未能将项目设置强制为给定的位大小,并且可能在其中一个项目中使用了任何CPU。
简短版本:如果您希望.NET代码具有特定的位大小,请强制执行项目设置。
您发布的VB.NET和C#代码都将并且应该产生相同的结果-这是选择两个项目中的CPU相同的项目设置的问题。

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