I've built a Windows service as “Any CPU”. Why does it run in 32-bit mode on my 64 bit machine? [duplicate]

空扰寡人 提交于 2019-12-03 09:21:00

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.

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

  <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>

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:

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'

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

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 takes effect immediately.

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.

WhiteKnight

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

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:

corflags.exe WindowService.exe /32bit-

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

  1. x64: AnyCPU assemblies with use JIT to compile x64 versions of the assemblies (slow). x86 assemblies will get a BadImageFormatException.
  2. x86: AnyCPU assemblies JIT to x86. x64 assemblies will get a BadImageFormatException.
  3. AnyCPU: .Net will default to x86. See above.

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!