E
Ed Kramer
Greetings,
I am a C# software developer and I'm having some issues with running
applications on both 32 bit and 64 bit architecture. After an extensive
amount of net searching I have found several ways of detection at runtime
each with it's own pitfalls and levels of confidence. In our shop we have
mostly 32 bit machines and 32 bit Operating systems, though we have a few 64
bit machines available outside the office (my home Pc for example). I assume
we will eventually get rid of our w32 machines but I don't know when that
will happen and our code needs to run on both architectures. Our assemblies
are all built as 'Any CPU' rather than as x86 or x64 so that we don't have to
compile two different sets of binaries. So I suppose what I need to know is:
How do I determine what platform I am running under at both run and build
time?
At build time...
I am asking about this because the 32 bit SDK doesnt' work on a 64 bit
machine so the tools for signing, strong naming and manifesting are installed
in a different location on w7 x64 than it would be on Windows XP 32 bit. So
if I create a post build event to handle signing, strong naming and
manifesting it would need to be aware of which platform it is running on so
it can look for the correct mt.exe, sn.exe and signtool.exe whether it is
building on my home x64 W7 machine or at my WinXp 32 machine at work. is
there a macro or pre-processor define or something that can I can reference
in my post build event so I know which path to these executables to use?
Knowing what to use in my post build event would also make my build script
functional. I do work from home on a 64 bit windows 7 machine, and when I
attempt to build, all of my assembly prep fails because the CLR SDK 2.0 is at
a different path than on my 32 bit XP machine at work. Since we have around
30 projects, having to go through each post-build event and REM out the
command line pointing to the 32 bit SDK and remove REM from the 64 bit
command line. Which really isn't fun after the first time you do it. Having a
preprocessor directive or something that could switch between the two would
be preferable because then it would just build no matter what machine I put
it on (assuming you installed the SDK to the default location).
At run time...
Since most of our code revolves around windows services and a utility to
configure them you would think not knowing about architecture would be fine.
However, the configuration utility does look in the registry to find the
install path placed there by our Wix installer. On a 64 bit system, this data
ends up under the Wow6432Node whereas on a 32 bit system it ends up under
HKLM\Software\<manufacturer>\<product>. The Wix installer just shoves it in
there and the underlying OS just handles it. Whereas when I fire up the C#
code, there is no special shim or redirect to put me into Wow6432Node if I
specify the 32 bit version of my path. So, I need to know ahead of time which
architecture I'm running under so i can specify the right path. There is of
course some other things as well but this is the one that most readily comes
to mind.
Thus far I've seen the following run time recommendations
1. Check the size of an Intptr. if it's 4 bytes, then you're on a 32 bit.. 8
bytes and you're on 64 bit - But if you're running as a 32 bit process on a
64 bit OS, this is going to return 4 bytes, not 8.
2. Use the Windows API call IsWow64Process - but this only tells you if your
PROCESS is 32 or 64 bit, not your OS. So the same thing as above. My process
may well be 32, but if you're on a 64 bit OS your registry settings aren't
where you expect them to be.
3. Use the environment variable 'PROCESSOR_ARCHITECTURE'. If you are on a 64
bit processor, it will have the characters '64' in it. - I can't say I like
the idea of searching a string for my answers when it might well change
without notice. Also, this doesnt' tell me what the installed OS is as far as
I can tell. You can have a 64 bit processor architecture running a 32 bit OS.
But thus far this is the closest to what I'm looking for.
4. My own idea would be to open the registry and look for the Wow6432Node.
If it's there, then you're running 64 bit, if not you are running 32 bit.
And during unit tests...
I've created a class which wraps all of the different methods of testing for
architecture specs and I'd like to exercise the methods using Nunit unit
testing. Unfortunately without a way for me to definitively KNOW what
architecture I'm running on I cannot be sure that the methods in my classes
are returning the correct value. I could of course make an assumption and
hard code something but that cancels out the idea of being able to run nunit
on any system and have the unit tests still work. The whole point of unit
tests is to remove the human element as much as possible from testing so as
to reduce human error, having to remember to go in and change a setting to
test on 64 or 32 bit would introduce unnecessary human errors into the mix.
Any help on this would be appreciated. Maybe I'm making this a bit more
complicated than it need be or perhaps I'm jus confused, but it appears like
a bit of a catch 22 to me from my perspective. I can't get the code to work
right unless I can detect my architecture but I can't use some reliable way
to detect it so I have to write my own detection routines... but I can't know
they're correct because I can't detect my architecture in a reliable way to
test them.
Thanks,
Ek
I am a C# software developer and I'm having some issues with running
applications on both 32 bit and 64 bit architecture. After an extensive
amount of net searching I have found several ways of detection at runtime
each with it's own pitfalls and levels of confidence. In our shop we have
mostly 32 bit machines and 32 bit Operating systems, though we have a few 64
bit machines available outside the office (my home Pc for example). I assume
we will eventually get rid of our w32 machines but I don't know when that
will happen and our code needs to run on both architectures. Our assemblies
are all built as 'Any CPU' rather than as x86 or x64 so that we don't have to
compile two different sets of binaries. So I suppose what I need to know is:
How do I determine what platform I am running under at both run and build
time?
At build time...
I am asking about this because the 32 bit SDK doesnt' work on a 64 bit
machine so the tools for signing, strong naming and manifesting are installed
in a different location on w7 x64 than it would be on Windows XP 32 bit. So
if I create a post build event to handle signing, strong naming and
manifesting it would need to be aware of which platform it is running on so
it can look for the correct mt.exe, sn.exe and signtool.exe whether it is
building on my home x64 W7 machine or at my WinXp 32 machine at work. is
there a macro or pre-processor define or something that can I can reference
in my post build event so I know which path to these executables to use?
Knowing what to use in my post build event would also make my build script
functional. I do work from home on a 64 bit windows 7 machine, and when I
attempt to build, all of my assembly prep fails because the CLR SDK 2.0 is at
a different path than on my 32 bit XP machine at work. Since we have around
30 projects, having to go through each post-build event and REM out the
command line pointing to the 32 bit SDK and remove REM from the 64 bit
command line. Which really isn't fun after the first time you do it. Having a
preprocessor directive or something that could switch between the two would
be preferable because then it would just build no matter what machine I put
it on (assuming you installed the SDK to the default location).
At run time...
Since most of our code revolves around windows services and a utility to
configure them you would think not knowing about architecture would be fine.
However, the configuration utility does look in the registry to find the
install path placed there by our Wix installer. On a 64 bit system, this data
ends up under the Wow6432Node whereas on a 32 bit system it ends up under
HKLM\Software\<manufacturer>\<product>. The Wix installer just shoves it in
there and the underlying OS just handles it. Whereas when I fire up the C#
code, there is no special shim or redirect to put me into Wow6432Node if I
specify the 32 bit version of my path. So, I need to know ahead of time which
architecture I'm running under so i can specify the right path. There is of
course some other things as well but this is the one that most readily comes
to mind.
Thus far I've seen the following run time recommendations
1. Check the size of an Intptr. if it's 4 bytes, then you're on a 32 bit.. 8
bytes and you're on 64 bit - But if you're running as a 32 bit process on a
64 bit OS, this is going to return 4 bytes, not 8.
2. Use the Windows API call IsWow64Process - but this only tells you if your
PROCESS is 32 or 64 bit, not your OS. So the same thing as above. My process
may well be 32, but if you're on a 64 bit OS your registry settings aren't
where you expect them to be.
3. Use the environment variable 'PROCESSOR_ARCHITECTURE'. If you are on a 64
bit processor, it will have the characters '64' in it. - I can't say I like
the idea of searching a string for my answers when it might well change
without notice. Also, this doesnt' tell me what the installed OS is as far as
I can tell. You can have a 64 bit processor architecture running a 32 bit OS.
But thus far this is the closest to what I'm looking for.
4. My own idea would be to open the registry and look for the Wow6432Node.
If it's there, then you're running 64 bit, if not you are running 32 bit.
And during unit tests...
I've created a class which wraps all of the different methods of testing for
architecture specs and I'd like to exercise the methods using Nunit unit
testing. Unfortunately without a way for me to definitively KNOW what
architecture I'm running on I cannot be sure that the methods in my classes
are returning the correct value. I could of course make an assumption and
hard code something but that cancels out the idea of being able to run nunit
on any system and have the unit tests still work. The whole point of unit
tests is to remove the human element as much as possible from testing so as
to reduce human error, having to remember to go in and change a setting to
test on 64 or 32 bit would introduce unnecessary human errors into the mix.
Any help on this would be appreciated. Maybe I'm making this a bit more
complicated than it need be or perhaps I'm jus confused, but it appears like
a bit of a catch 22 to me from my perspective. I can't get the code to work
right unless I can detect my architecture but I can't use some reliable way
to detect it so I have to write my own detection routines... but I can't know
they're correct because I can't detect my architecture in a reliable way to
test them.
Thanks,
Ek