41

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.

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.

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?

4
  • 2
    That's a first. Use Corflags.exe to double-check. Commented Mar 26, 2010 at 0:27
  • Do you have any dependent assemblies that are compiled 32-bit only? Commented Mar 26, 2010 at 6:18
  • I just wanted to mention that the same problem was discussed here social.msdn.microsoft.com/Forums/en/netfx64bit/thread/… Sadly no solution was provided. I'm facing the exact same problem. Commented Nov 4, 2010 at 13:06
  • 3
    Late to the game, but this is a different issue than the referred question... no a duplicate... Commented Nov 7, 2016 at 8:06

4 Answers 4

20

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> 
Sign up to request clarification or add additional context in comments.

2 Comments

You actually need to set the flag to "false" - in my case the config entry was not existing, and yet VS compiled with "prefer 32". There is a setting in VS 2015 under "build" to enable / disable this. Disabling it, adds an entry in the .csproj with "<Prefer32Bit>false</Prefer32Bit>"
I believe this flag is from some older version of Visual Studio. On Visual Studio 2015 I'm not seeing this tag Prefer32Bit when I open my *.csproj file in a text editor.
17

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.

Comments

2

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- 

1 Comment

-1

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.

6 Comments

The msdn says something different: msdn.microsoft.com/en-us/library/zekwfyz4.aspx "On a 64-bit Windows operating system ... - Executables compiled with the /platform:anycpu will execute on the 64 bit CLR - DLLs compiled with the /platform:anycpu will execute on the same CLR as the process into which it is being loaded"
the 2GB limit applies to all 32-bit process, not only .NET ones. Apps linked with /LARGEADDRESSAWARE option can use maximum 3GB of RAM (or 4GB on windows 64 bit) en.wikipedia.org/wiki/3_GB_barrier
@phuclv, it is possible to use that option even with .NET apps: stackoverflow.com/a/1346510/2157640
@Palec and how does that relate to my comment? When did I said that it doesn't work with .NET? I said the 2GB limit has nothing to do with .NET, and the flag will increase the limit to 3GB in 32-bit Windows and 4GB in 64-bit Windows
AnyCPU: .Net will default to x86 this is absolutely wrong. It'll compile to x86, x86-64, ARM32 or ARM64 depending on the loading process. Only the new Any CPU 32-bit preferred option will compile to x86 or ARM32 even on 64-bit Windows
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.