views:

2966

answers:

4

In 64 bit versions of windows, 32 bit software is installed in "c:\program files (x86)". This means you cannot use $(programfiles) to get the path to (32 bit) software. So I need a $(programfiles32) to overcome this in my msbuild project. I don't want to change the project depending on the os it is running on.

I have a solution which I will post, but maybe there is a easier/better way.

+8  A: 

My solution is to look whether "c:\program files (x86)" exists, if it exists, asume this is a 64 bit os. Otherwise use the normal program files directory:

<PropertyGroup>
  <ProgramFiles32 Condition="Exists('$(PROGRAMFILES) (x86)')">$(PROGRAMFILES) (x86)</ProgramFiles32>
  <ProgramFiles32 Condition="$(ProgramFiles32) == ''">$(PROGRAMFILES)</ProgramFiles32>
</PropertyGroup>

I can use it like this

<Exec WorkingDirectory="src\app1" Command='"$(ProgramFiles32)\doxygen\bin\doxygen" Doxyfile' />
Wimmel
This will break horribly on non-english versions of Windows, as program files is not always called program files.
jalf
I think the environment variable %programfiles% points to the program files directory in any language. And at least in German the 32 bits version adds just " (x86)": http://www.tipps-fuer-windows-vista.de/img/Navigation/Navi1.gif Don't know about japanese though.
Wimmel
You need to check for an environment variable called %ProgramFiles(x86)%. If that exists, then you're on a 64-bit OS, and that's the path you want. If it doesn't exist, then use the path specified by %ProgramFiles%.
RobH
Using Condition="Exists('$(PROGRAMFILES) (x86)')" searches for C:\Program Files (x86) (x86) in the msbuild from .net 4.0.21006
Jedidja
+3  A: 

I think a slighly more reliable way is to grab the Environment variable "ProgramFiles(x86)". In a 64 bit process on Windows this will point to the 32 bit program files directory. It will be empty on a 32 bit version of windows and I believe on a wow64 process

I ran into virtually same problem recently with some PowerShell scripts. I wrote a blog entry on how a worked around the program files directory issue. Different language obviously but it may help you out.

http://blogs.msdn.com/jaredpar/archive/2008/10/21/program-files-i-just-want-the-32-bit-version.aspx

JaredPar
tried it, but it does not work. "$(PROGRAMFILES(x86))" evaluates to ")". So it looks like it in not possible in msbuild to use an environment variable which includes a ')' character. I did not see anything else in the environment which can be used instead.
Wimmel
Did you try escaping the ('s? I'm not a heavy msbuild user so i don't know if this is possible or not
JaredPar
escaping with a backslash or single quotes did not work. But I'm also not a heavy msbuild user. Probably should ask a new question the escaping...
Wimmel
Yeah, I couldn't ever get it to evaluate either. I used Wimmel's solution. It works.
Brendan Enrick
+1; syntax for escaping is $(ProgramFiles%28x86%29) See http://msdn.microsoft.com/en-us/library/ms228186%28VS.80%29.aspx
Ruben Bartelink
+5  A: 

Try "$(MSBuildExtensionsPath32).." Dan

There was meant to be a slash before the double dot. Maybe I mistyped or the web page ate it.
With the slash it works fine. And it looks cleaner than my solution. This is how I used it: <PropertyGroup> <ProgramFiles32>$(MSBuildExtensionsPath32)\..</ProgramFiles32> </PropertyGroup>
Wimmel
A: 

I stumbled across this question trying to find a generic way in MSbuild to see if it was a 32- or 64-bit os. In case someone else also find this, I used the following:

<PropertyGroup>
  <OSBits Condition="$(ProgramW6432) != ''">x64</OSBits>
  <OSBits Condition="$(OSBits) == ''">x32</OSBits>
</PropertyGroup>

Apparently %ProgramW6432% is only set on 64-bit systems.

Jedidja