2008-12-06 25 views
34

En versiones de 64 bits de Windows, el software de 32 bits se instala en "c: \ archivos de programa (x86)". Esto significa que no puede usar $ (archivos de programa) para obtener la ruta al software (32 bits). Entonces necesito $ (ProgramFiles32) para superar esto en mi proyecto MSBuild. No quiero cambiar el proyecto dependiendo del sistema operativo en el que se ejecuta.Utilice el directorio "Archivos de programa" de 32 bits en msbuild

Tengo una solución que publicaré, pero tal vez hay una manera más fácil/mejor.

+0

Muchas de las respuestas se vuelven un poco quisquillosas sobre si una respuesta determinada funcionará en .NET 2.0 y 4.0, pero no lo veo en la pregunta. Quizás nos puede decir qué versión (s) de .NET que planea apuntar? – BrainSlugs83

+0

@ BrainSlugs83 Esta pregunta se realizó en 2008 cuando .net 4.0 aún no existía. Pero en general, siempre preferiría una solución que funcione en cualquier versión, para evitar tener que hacer cambios al cambiar de versión. La respuesta aceptada explica qué usar en las versiones más nuevas de msbuild, pero también proporciona una solución para versiones anteriores que también funciona en versiones más nuevas. Entonces, no veo el punto de limitar mi pregunta a una versión específica. – wimh

Respuesta

38

En MSBuild 4.0+, hay a $(MSBuildProgramFiles32) property por ello, que con confianza puede emplear directamente (especialmente si usted está dispuesto a poner un ToolsVersion="4.0" en la parte superior del archivo para garantizar que va a estar disponible y Fail Fast si no lo es) .

Si no estás y necesita algo que puede hacer lo correcto, incluso cuando se ejecuta en un entorno de MSBuild 2.0 o posterior (es decir, volver a VS 2005 ambientes), la solución completa es:

<PropertyGroup> 
    <!--MSBuild 4.0 property--> 
    <ProgramFiles32>$(MSBuildProgramFiles32)</ProgramFiles32> 
    <!--Use OS env var as a fallback:- 32 bit MSBuild 2.0/3.5 on x64 will use this--> 
    <ProgramFiles32 Condition=" '' == '$(ProgramFiles32)'">$(ProgramFiles%28x86%29)</ProgramFiles32> 

    <!-- Handle MSBuild 2.0/3.5 running in 64 bit mode - neither of the above env vars are available. http://stackoverflow.com/questions/336633 
     NB this trick (Adding a literal " (x86)" to the 64 bit Program Files path) may or may not work on all versions/locales of Windows --> 
    <ProgramFiles32 Condition ="'$(ProgramFiles32)'=='' AND 'AMD64' == '$(PROCESSOR_ARCHITECTURE)'">$(ProgramFiles) (x86)</ProgramFiles32> 

    <!--Catch-all - handles .NET 2.0/3.5 non-AMD64 and .NET 2.0 on x86 --> 
    <ProgramFiles32 Condition=" '' == '$(ProgramFiles32)' ">$(ProgramFiles)</ProgramFiles32> 
</PropertyGroup> 

Desafortunadamente Progressive enhancement/polyfill se omite el nombre MSBuild reserved propertyMSBuildProgramFiles32 a través de un <PropertyGroup> o <CreateProperty> es rechazado por MSBuild 4.0+ por lo que no se puede hacer más ordenado y todavía es compatible con .NET 2.0.

+1

La mejora progresiva me da este error en MSBuild 4: 'error MSB4004: la propiedad" MSBuildProgramFiles32 "está reservada, y no se puede modificar. – Wernight

+0

@Wernight Gracias por la captura: eliminó las mejoras progresivas. Si tu comentario desaparece, eventualmente lo eliminaré. –

16

Mi solución es buscar si existe "c: \ archivos de programa (x86)", si existe, asume que se trata de un sistema operativo de 64 bits. De lo contrario usar el directorio de archivos de programa normales:

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

que puede utilizar de esta manera

<Exec WorkingDirectory="src\app1" Command='"$(ProgramFiles32)\doxygen\bin\doxygen" Doxyfile' /> 
+5

Esto se romperá horriblemente en versiones no inglesas de Windows, ya que los archivos de programa no siempre se llaman archivos de programa. – jalf

+1

Creo que la variable de entorno% programfiles% apunta al directorio de archivos de programa en cualquier idioma. Y al menos en alemán, la versión de 32 bits agrega solo "(x86)": http://www.tipps-fuer-windows-vista.de/img/Navigation/Navi1.gif. Sin embargo, no sé nada de japonés. – wimh

+3

Necesita buscar una variable de entorno llamada% ProgramFiles (x86)%. Si eso existe, entonces tiene un sistema operativo de 64 bits, y esa es la ruta que desea. Si no existe, utilice la ruta especificada por% ProgramFiles%. – RobH

4

Creo que una forma ligeramente más fiable es agarrar los "Archivos de programa (x86)" variable de entorno. En un proceso de 64 bits en Windows, esto apuntará al directorio de archivos de programa de 32 bits. Va a estar vacío en una versión de 32 bits de Windows y creo cree en un proceso wow64

Me encontré con prácticamente el mismo problema recientemente con algunos scripts de PowerShell. Escribí una entrada de blog sobre cómo se solucionó el problema del directorio de archivos del programa. Diferente lenguaje obviamente pero puede ayudarte.

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

+0

lo intenté, pero no funciona. "$ (PROGRAMFILES (x86))" evalúa a ")". Por lo tanto, parece que no es posible en msbuild utilizar una variable de entorno que incluye un carácter ')'. No vi nada más en el entorno que pueda usarse en su lugar. – wimh

+0

¿Intentó escapar de (no soy un usuario pesado de msbuild así que no sé si esto es posible o no – JaredPar

+0

escapando con una barra invertida o las comillas simples no funcionaron, pero tampoco soy pesado msbuild user. Probablemente debería hacer una nueva pregunta sobre el escape ... – wimh

8

Try "$(MSBuildExtensionsPath32)\.."

+0

Se suponía que debía haber una barra antes del doble punto. Tal vez lo escribí mal o la página web se lo comió. –

+0

Con la barra, funciona bien. Y se ve más limpio que mi solución. Así es como lo usé: $ (MSBuildExtensionsPath32) \ .. wimh

+0

-1 Este enfoque no agrega nada. Si MSBuildExtensionsPath32 está disponible, MSBuildProgramFiles32 también estará disponible. (Probado: esto definitivamente no es compatible con FW 2 MSBuild (inc al especificar una versión de Tools 3.5) a pesar de lo que [esta publicación] (http://www.sedodream.com/PermaLink,guid,7e11f92e-e778-4e69-9441- 9a6be3512e71.aspx) sugiere) –

1

me encontré con esta pregunta tratando de encontrar una manera genérica en MSBUILD para ver si se trataba de un sistema operativo de 32 o 64 bits. En caso de que alguien más también encontrar esto, he utilizado la siguiente:

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

Al parecer %ProgramW6432% sólo se establece en sistemas de 64 bits.

+1

Considere formular la pregunta [como una pregunta de nivel superior] y contestarla usted mismo - generalmente se acepta como una buena cosa –

+0

Consulte también la variable 'PROCESSOR_ARCHITECTURE' (que puede ser, por ejemplo,' AMD64') para un control más estricto –

+0

Sí La pregunta de OP se puede resolver solo con $ (ProgramW6432). Supongo que esta variable no existía cuando OP publicó la pregunta. – smead

10

En MSBuild 4.0, $(MSBuildProgramFiles32) le proporcionará el directorio Archivos de programa de 32 bits.

+0

+1 Había escrito [mi respuesta] (http: // stackoverflow.com/questions/346175/use-32bit-program-files-directory-in-msbuild/5650767 # 5650767) antes de ver esto, así que espero que no se ofenda en la duplicación (el ejemplo sirve para explicar mi comentario sobre la respuesta de @JaredPar) –

+0

@ Ruben-Bartelink, me gusta la reserva que mencionas en tu respuesta. Así que elegí eso como una respuesta aceptada. – wimh

1

Si ejecuta la versión de 32 bits de las herramientas de Visual Studio (especialmente en VS2012, hay como 3 comando diferente le indica que puede elegir), $ (ProgramFiles) apunta a "Archivos de programa (x86)"

Cuestiones relacionadas