MSBuild and $(ProgramFiles) issue with 32/64 bits
Asked Answered
G

2

12

I wrote a custom MSBuild task which calls SubWCRev.exe, an executable which (typically) resides in C:\Program Files\TortoiseSVN\bin, whether it's 32 or 64 bits, since TortoiseSVN provides both versions.

The problem is, Visual Studio 2010 only has a 32 bit version. So when my colleagues with a 64 bit box try to build using my shiny new task, $(ProgramFiles) resolves to C:\Program Files(x86) and it explodes saying that SubWCRev.exe cannot be found. Because they have the 64 bit version of TortoiseSVN, which lives in C:\Program Files!

Is there a better solution than hardcoding C:\Program Files in my msbuild script, or having everyone use the 32 bit version of TortoiseSVN? (Actually it's a C# project, I tinkered with the MSBuild code a bit)

Ground answered 15/8, 2011 at 15:28 Comment(0)
W
16

Take a look it this:

<Project ToolsVersion="4.0" DefaultTargets="PrintValues" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="PrintValues">
    <PropertyGroup>
      <MyProgramFiles>$(ProgramW6432)</MyProgramFiles>
      <MyProgramFiles Condition="$(MyProgramFiles) == ''">$(ProgramFiles)</MyProgramFiles>
    </PropertyGroup>

    <Message Text="MyProgramFiles: $(MyProgramFiles)"/>
  </Target>

</Project>

This lets MyProgramFiles resolve to "C:\Program Files" for both 32 and 64 bit Windows (The ProgramW6432 environment variable is empty on non-64 bit versions of Windows).

Whiggism answered 15/8, 2011 at 16:47 Comment(0)
G
2

Use MSBuildExtensionsPath property instead of hardcoding the path.

Per MSDN:

The MSBuild subfolder under the \Program Files\ or \Program Files (x86) folder. This path always points to the Program Files of the same bitness as the window you are currently running in. For example, for a 32-bit window on a 64-bit machine, the path is to the Program Files (x86) folder. For a 64-bit window on a 64-bit machine, the path is to the Program Files folder. See also MSBuildExtensionsPath32 and MSBuildExtensionsPath64.

Edit: To get to the 64 bit SVN folder, use :

<PropertyGroup>
   <TortoiseSVNPath>$(MSBuildExtensionsPath64)\..\TortoiseSVN\bin</TortoiseSVNPath>
</PropertyGroup>

Another way is to check for existence of folders:

<PropertyGroup>
  <TortoiseSVNPath Condition="Exists('$(PROGRAMFILES) (x86)')">$(PROGRAMFILES) (x86)\TortoiseSVN\bin</TortoiseSVNPath>
  <TortoiseSVNPath Condition="$(TortoiseSVNPath) == ''">$(PROGRAMFILES)\TortoiseSVN\bin</TortoiseSVNPath>
</PropertyGroup>
Ginelle answered 15/8, 2011 at 15:37 Comment(7)
Sorry, I just tried it and it resolved to C:\Program Files (x86)\MSBuild. I'm positive it's a Windows 7 64-bit box, and Visual Studio is a 32 bit process (just checked with Process Explorer).Ground
That's the right behavior. For 32 bit VS, it should resolve to C:\Program Files (x86).... IS the MSBuild at the end an issue for you? $(MSBuildExtensionsPath)\.. will give the right Program Files folder.Ginelle
Yes, it is an issue, because even if I'm running the 32-bit Visual Studio, I want to call the 64-bit SubWCRev.exeGround
Then simply use $(MSBuildExtensionsPath64)..\TortoiseSVN\bin. MSBuildExtensionsPath64 will always point to 64 bit Program Files\MSBuild folderGinelle
But won't that variable be empty when I run it on a 32-bit Windows? Forgot to clarify that, we have Windows XP 32-bit boxes and Windows 7 64-bit boxes as well. We are still in a transition stage regarding our productsGround
But didn't you say you always wanted the 64 bit version? If that's not the case, then use the conditional check method to detect if one folder exists. Upto you if you first want to use 64 bit, if not fallback to 32 bit or vice versa. My answer checks for 32 bit first.Ginelle
Sorry, @Service Guy's answer came out as more straightforward to me. Thanks for your help, all the sameGround

© 2022 - 2024 — McMap. All rights reserved.