tags:

views:

42

answers:

2

I'd like to be able to distribute one version of an executable that a user can configure to run as either 32-bit or 64-bit. The service would have a 32-bit host process that would read configuration and launch new processes as 32 or 64-bit. What I haven't determined is how/if a executable targeted for Any CPU can be launched as a 32-bit process under 64-bit Windows.

A: 

Targeting Any CPU means that you are targeting the build machine's operating system. So if your build machine is 32-bit, then Any CPU will build a 32-bit output, and if your build machine is 64-bit, then you will get a 64-bit output. This has nothing to do with the machine you deploy to.

In order to achieve what you're looking to do, you will really need 2 copies of the exe, one as a 32-bit version and the other as 64-bit. You can do this by setting the Target platform to 32-bit and 64-bit respectively. Once again, if you target Any CPU, Visual Studio will pick up whichever OS is currently on the build machine.

code4life
Loading a Any CPU targeted library into a 32-bit process will build for 32-bit. So a 64-bit machine *can* build 32-bit code. I'm just wondering if it possible to force this in a new process.
dmo
That's my point, it will **build**, which means the output binary is going to be either 32-bit or 64-bit, never both. So that being the case, how can you launch a 64-bit built binary as a 32-bit process? The only way is to have both the 32/64 bit versions and launch either one per your configuration file.
code4life
MSIL is compiled to native code (32-bit or 64-bit) at runtime. The problem is how to instruct a 64-bit OS which to build. If the project is compiled as explicitly 32-bit or 64-bit, the runtime will respect that. If loaded in a running process, it will try to use the same as the hosting process. .NET binaries are compiled to MSIL so they can be run in any environment in principal.
dmo
+1  A: 

This makes little sense. If your app can run as a 32-bit process and doesn't need the extra virtual memory space then there's just no point in ever running it as a 64-bit process.

Nor can you easily control it. It requires changing a value in the .exe header. The Corflags.exe utility can do this, but you cannot distribute it. Hacking the headers yourself is technically possible but very fugly. The ultimate obstacle is that you don't typically have the write access that's required to modify the .exe file on a properly secured machine (ie UAC). If you really, really need to do this then just deploy two copies of the .exe

Which you can do by writing a very puny bootstrapper .exe. All it needs to do is Assembly.Load() the main .exe and call its Program.Main() method. Build two versions of it.

Hans Passant
I'm aware that it can be forced this way and that isn't workable. For most purposes, 64-bit will be preferred but 32-bit might be necessary for some backwards compatibility scenarios. Deploying 2 copies is the default position but I was hoping there was another way.
dmo
All you need is a very puny bootstrapper EXE. It can Assembly.Load() the main EXE and call its Program.Main() method.
Hans Passant
Thanks, Hans - this might be a reasonable approach.
dmo
Would you mind editing your answer to reflect this suggestion as I believe it is one others might find useful.
dmo
Minds thinking alike, I did while you posted that comment.
Hans Passant