我将Windows服务构建为“任意CPU”。为什么在我的64位机器上运行32位模式?(复制)

时间:2022-09-01 10:01:45

This question already has an answer here:

这个问题已经有了答案:

I've built a Windows service as "Any CPU". However, when I run it on my 64 bit machine it runs in 32 bit. How can I fix it? I'm using .NET and C#, and my operating system is Windows 2008 R2.

我将Windows服务构建为“任意CPU”。但是,当我在64位机器上运行时,它的运行速度是32位。我怎样才能修好它呢?我使用。net和c#,我的操作系统是Windows 2008 R2。

If I build it in x64 it correctly loads in 64 bit mode. However, "Any Cpu" -- which is what I want -- loads in 32 bit, even though the machine it's running on perfectly supports 64 bit.

如果我在x64中构建它,它会正确地以64位模式加载。然而,“任何Cpu”——这是我想要的——加载32位,即使它运行的机器完全支持64位。

EDIT to add more information based on feedback

根据反馈添加更多信息

We do have third party tools as well as reference a c++ managed assembly. These may or may not be built for any CPU. In fact i know that the c++ managed assembly is only built for x86. However, the odd things is that if I specifically specify x64 the process will start up and work in x64. If the framework were to attempt to load the c++ managed assembly it would fail. I don't mind this, because in the code, we do not load the 32bit managed ++ assembly if we're running in 64 bit mode. Could it be that the build figures that since there is a 32 bit assembly in here it should mark the launching process (in this case a windows service assembly) as x86?

我们确实有第三方工具以及引用c++托管程序集。这些可能是为任何CPU构建的,也可能不是。事实上,我知道c++托管程序集只针对x86构建。然而,奇怪的是,如果我特别指定x64,流程将在x64中启动和工作。如果框架试图加载c++托管程序集,它将失败。我不介意这个,因为在代码中,如果在64位模式下运行,我们不会加载32位托管+程序集。因为这里有一个32位的程序集,它应该将启动过程(在本例中是windows服务程序集)标记为x86吗?

4 个解决方案

#1


15  

In case anybody runs across the same thing I did: I had created two new config settings (copied from the Debug config). For some reason "Prefer32Bit" flag was set to true, even though the checkbox was greyed out and unchecked in the project config page.

如果有人遇到我所做的事情:我创建了两个新的配置设置(从调试配置中复制)。由于某些原因,“prefer32位”标志被设置为true,即使复选框在项目配置页面中被删除和未选中。

You can fix it by removing the line directly from the .csproj file.

您可以通过直接从.csproj文件中删除行来修复它。

  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Staging|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Staging\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>true</Prefer32Bit> <!-- REMOVE THIS LINE -->
  </PropertyGroup>

#2


12  

There's a setting that can force AnyCPU assemblies to run as 32-bit on x64 OS.
Use ldr64.exe from .Net2 x64 directory to check the status:

有一种设置可以强制任何cpu程序集在x64操作系统上以32位的方式运行。使用ldr64。exe从.Net2 x64目录检查状态:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727>ldr64.exe query
loading kernel32...done.
retrieved GetComPlusPackageInstallStatus entry point
retrieved SetComPlusPackageInstallStatus entry point
Current status is: 0x00000001

1 - means 'run AnyCPU as 64-bit'
0 - means 'run AnyCPU as 32-bit'

1 -表示“以64位的方式运行任何cpu”-表示“以32位的方式运行任何cpu”

Though I didn't find such utility in .Net v4 folder, the setting applies to Net4 AnyCPU assemblies as well. This flag is saved in DWORD registry value Enable64Bit under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework

虽然我在。net v4文件夹中没有找到这样的实用程序,但是这个设置也适用于Net4 AnyCPU程序集。此标志保存在DWORD注册表值启用64位的关键HKEY_LOCAL_MACHINE\软件\Microsoft\.NETFramework中

This setting seems to be loaded on OS start, and changing only registry value doesn't affect applications until reboot. Changing the flag with ldr64.exe affects immediately.

这个设置似乎是在OS start上加载的,并且在重新启动之前,只修改注册表值不会影响应用程序。用ldr64改变国旗。exe立即影响。

Note that this setting is system-wide. By default Enable64Bit is set to 1. It seems that some application reset it to 0, and reverting the value back can cause problem to that app.

注意,此设置是系统范围的。默认情况下,Enable64Bit被设置为1。似乎某些应用程序将它重置为0,然后返回值会给该应用程序带来问题。

#3


1  

Thanks to this answer. I use CorFlags to get it to run as 64 bit

多亏了这个答案。我用CorFlags让它以64位运行

corflags.exe WindowService.exe /32bitpref- /32bitreq-

The version of CorFlags that I used was 4.0.30319.17929, which I found in C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools. You could try the older versions with the following:

4.0.30319.17929 CorFlags我使用的版本,我发现在C:\Program Files (x86)\Microsoft sdk \ Windows \ v8.0A \ bin \ NETFX 4.0工具。您可以尝试旧版本,如下:

corflags.exe WindowService.exe /32bit-

#4


-1  

If the app exe which starts the CLR is compiled as:

如果启动CLR的app exe被编译为:

  1. x64: AnyCPU assemblies with use JIT to compile x64 versions of the assemblies (slow). x86 assemblies will get a BadImageFormatException.
  2. x64:使用JIT编译x64版本的程序集的任何cpu程序集(速度很慢)。x86程序集将获得一个BadImageFormatException。
  3. x86: AnyCPU assemblies JIT to x86. x64 assemblies will get a BadImageFormatException.
  4. x86: AnyCPU程序集JIT到x86。x64程序集将获得一个BadImageFormatException。
  5. AnyCPU: .Net will default to x86. See above.
  6. . net默认为x86。见上图。

I often use a starter application, where I explicitly compile the .exe as x64 or x86 and ship x86 and x86 versions of the .msi. This is probably the easiest route - The performance gain is generally worth the overhead of managing additional files.

我经常使用starter应用程序,在其中显式地将.exe编译为x64或x86,并将.msi的x86和x86版本发布。这可能是最简单的途径——性能的提高通常值得管理其他文件的开销。

Alternatively, you can use ngen during the setup process, which will do all the JIT stuff when the application is installed. You will notice improved start-up times for your application.

或者,您可以在安装过程中使用ngen,它将在安装应用程序时完成所有的JIT工作。您将注意到应用程序的启动时间得到了改进。

Also, as I recently discovered with x86 applications, there is a 2GB memory limit for .net applications. This occurs even when you have 4gb of ram on your x86 and have heaps of memory left over.

另外,正如我最近在x86应用程序中发现的,.net应用程序有2GB的内存限制。即使在x86上有4gb的ram,并且有大量的内存,这种情况也会发生。

#1


15  

In case anybody runs across the same thing I did: I had created two new config settings (copied from the Debug config). For some reason "Prefer32Bit" flag was set to true, even though the checkbox was greyed out and unchecked in the project config page.

如果有人遇到我所做的事情:我创建了两个新的配置设置(从调试配置中复制)。由于某些原因,“prefer32位”标志被设置为true,即使复选框在项目配置页面中被删除和未选中。

You can fix it by removing the line directly from the .csproj file.

您可以通过直接从.csproj文件中删除行来修复它。

  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Staging|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Staging\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>true</Prefer32Bit> <!-- REMOVE THIS LINE -->
  </PropertyGroup>

#2


12  

There's a setting that can force AnyCPU assemblies to run as 32-bit on x64 OS.
Use ldr64.exe from .Net2 x64 directory to check the status:

有一种设置可以强制任何cpu程序集在x64操作系统上以32位的方式运行。使用ldr64。exe从.Net2 x64目录检查状态:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727>ldr64.exe query
loading kernel32...done.
retrieved GetComPlusPackageInstallStatus entry point
retrieved SetComPlusPackageInstallStatus entry point
Current status is: 0x00000001

1 - means 'run AnyCPU as 64-bit'
0 - means 'run AnyCPU as 32-bit'

1 -表示“以64位的方式运行任何cpu”-表示“以32位的方式运行任何cpu”

Though I didn't find such utility in .Net v4 folder, the setting applies to Net4 AnyCPU assemblies as well. This flag is saved in DWORD registry value Enable64Bit under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework

虽然我在。net v4文件夹中没有找到这样的实用程序,但是这个设置也适用于Net4 AnyCPU程序集。此标志保存在DWORD注册表值启用64位的关键HKEY_LOCAL_MACHINE\软件\Microsoft\.NETFramework中

This setting seems to be loaded on OS start, and changing only registry value doesn't affect applications until reboot. Changing the flag with ldr64.exe affects immediately.

这个设置似乎是在OS start上加载的,并且在重新启动之前,只修改注册表值不会影响应用程序。用ldr64改变国旗。exe立即影响。

Note that this setting is system-wide. By default Enable64Bit is set to 1. It seems that some application reset it to 0, and reverting the value back can cause problem to that app.

注意,此设置是系统范围的。默认情况下,Enable64Bit被设置为1。似乎某些应用程序将它重置为0,然后返回值会给该应用程序带来问题。

#3


1  

Thanks to this answer. I use CorFlags to get it to run as 64 bit

多亏了这个答案。我用CorFlags让它以64位运行

corflags.exe WindowService.exe /32bitpref- /32bitreq-

The version of CorFlags that I used was 4.0.30319.17929, which I found in C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools. You could try the older versions with the following:

4.0.30319.17929 CorFlags我使用的版本,我发现在C:\Program Files (x86)\Microsoft sdk \ Windows \ v8.0A \ bin \ NETFX 4.0工具。您可以尝试旧版本,如下:

corflags.exe WindowService.exe /32bit-

#4


-1  

If the app exe which starts the CLR is compiled as:

如果启动CLR的app exe被编译为:

  1. x64: AnyCPU assemblies with use JIT to compile x64 versions of the assemblies (slow). x86 assemblies will get a BadImageFormatException.
  2. x64:使用JIT编译x64版本的程序集的任何cpu程序集(速度很慢)。x86程序集将获得一个BadImageFormatException。
  3. x86: AnyCPU assemblies JIT to x86. x64 assemblies will get a BadImageFormatException.
  4. x86: AnyCPU程序集JIT到x86。x64程序集将获得一个BadImageFormatException。
  5. AnyCPU: .Net will default to x86. See above.
  6. . net默认为x86。见上图。

I often use a starter application, where I explicitly compile the .exe as x64 or x86 and ship x86 and x86 versions of the .msi. This is probably the easiest route - The performance gain is generally worth the overhead of managing additional files.

我经常使用starter应用程序,在其中显式地将.exe编译为x64或x86,并将.msi的x86和x86版本发布。这可能是最简单的途径——性能的提高通常值得管理其他文件的开销。

Alternatively, you can use ngen during the setup process, which will do all the JIT stuff when the application is installed. You will notice improved start-up times for your application.

或者,您可以在安装过程中使用ngen,它将在安装应用程序时完成所有的JIT工作。您将注意到应用程序的启动时间得到了改进。

Also, as I recently discovered with x86 applications, there is a 2GB memory limit for .net applications. This occurs even when you have 4gb of ram on your x86 and have heaps of memory left over.

另外,正如我最近在x86应用程序中发现的,.net应用程序有2GB的内存限制。即使在x86上有4gb的ram,并且有大量的内存,这种情况也会发生。