【问题标题】:Use 32bit "Program Files" directory in msbuild在 msbuild 中使用 32 位“程序文件”目录
【发布时间】:2010-09-25 15:51:40
【问题描述】:

在 64 位版本的 windows 中,32 位软件安装在“c:\program files (x86)”中。这意味着您不能使用 $(programfiles) 来获取(32 位)软件的路径。所以我需要一个 $(ProgramFiles32) 在我的 MSBuild 项目中克服这个问题。我不想根据运行的操作系统更改项目。

我将发布一个解决方案,但也许有更简单/更好的方法。

【问题讨论】:

  • 对于给定的答案是否适用于 .NET 2.0 和 4.0,很多答案都变得有点挑剔——但我没有在问题中看到它——也许你可以告诉我们您打算针对哪个版本的 .NET?
  • @BrainSlugs83 这个问题是在 2008 年提出的,当时 .net 4.0 还不存在。但一般来说,我总是更喜欢适用于任何版本的解决方案,以避免在切换版本时进行更改。接受的答案解释了在较新的 msbuild 版本中使用什么,但也为旧版本提供了一个解决方案,该解决方案也适用于新版本。所以我看不出将我的问题限制在特定版本的意义。

标签: msbuild x86 64-bit x86-64 program-files


【解决方案1】:

如果您运行 32 位版本的 Visual Studio 工具(尤其是在 VS2012 中,您可以选择 3 种不同的命令提示符),$(ProgramFiles) 指向“Program Files (x86)”

【讨论】:

    【解决方案2】:

    在 MSBuild 4.0+ 中,有 a $(MSBuildProgramFiles32) property 用于它,您可以放心地直接使用它(特别是如果您准备在文件顶部放置 ToolsVersion="4.0" 以确保它可用并且 @987654322 @ 如果不是)。

    如果您不需要并且需要即使在 MSBuild 2.0 或更高版本的环境中执行(即回到 VS 2005 环境)也能做正确的事情,完整的解决方案是:

    <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>
    

    不幸的是,Progressive enhancement / polyfill 通过 &lt;PropertyGroup&gt;&lt;CreateProperty&gt; 覆盖 MSBuild reserved property 名称 MSBuildProgramFiles32 被 MSBuild 4.0+ 拒绝,因此它不能变得更整洁并且仍然支持 .NET 2.0.

    【讨论】:

    • 渐进式增强在 MSBuild 4 上给了我这个错误:error MSB4004: The "MSBuildProgramFiles32" property is reserved, and cannot be modified.
    • @Wernight 感谢您的发现 - 删除了渐进增强的内容。如果您的评论消失了,我最终会设法删除它!
    【解决方案3】:

    在 MSBuild 4.0 中,$(MSBuildProgramFiles32) 将为您提供 32 位 Program Files 目录。

    【讨论】:

    • +1 在我看到这个之前写过my answer,所以希望在重复时不要冒犯(这个例子用来解释我对@JaredPar 的回答的评论)
    • @Ruben-Bartelink,我喜欢你在回答中提到的后备方案。所以我选择了这个作为接受的答案。
    【解决方案4】:

    试试"$(MSBuildExtensionsPath32)\.."

    【讨论】:

    • 双点之前应该有一个斜线。可能是我打错了,或者网页把它吃掉了。
    • 使用斜线可以正常工作。它看起来比我的解决方案更干净。这就是我使用它的方式: $(MSBuildExtensionsPath32)\..
    • -1 这种方法不会添加任何东西。如果 MSBuildExtensionsPath32 可用,则 MSBuildProgramFiles32 也将可用。 (经过测试 - 尽管this post 建议,但 FW 2 MSBuild 绝对不支持此功能(包括在指定 ToolsVersion 3.5 时)
    • 如果您使用的是 dotnet.exe,则会解析为 C:\Program Files\dotnet\sdk\...
    【解决方案5】:

    我偶然发现了这个问题,试图在 MSbuild 中找到一种通用方法来查看它是 32 位还是 64 位操作系统。万一其他人也发现了这个,我使用了以下内容:

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

    显然%ProgramW6432% 仅在 64 位系统上设置。

    【讨论】:

    • 考虑提出这个问题 [作为顶级问题] 并自己回答——这通常被认为是一件好事
    • 另请参阅PROCESSOR_ARCHITECTURE(例如,AMD64)变量以进行更严格的控制
    • 是的,只要用 $(ProgramW6432) 就可以解决 OP 的问题。我猜当 OP 发布问题时这个变量不存在。
    【解决方案6】:

    我认为更可靠的方法是获取环境变量“ProgramFiles(x86)”。在 Windows 上的 64 位进程中,这将指向 32 位程序文件目录。在 32 位版本的 windows 上它将是空的,我 相信 在 wow64 进程上

    我最近在使用一些 PowerShell 脚本时遇到了几乎相同的问题。我写了一篇关于如何解决程序文件目录问题的博客文章。显然是不同的语言,但它可能会对您有所帮助。

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

    【讨论】:

    • 试过了,还是不行。 "$(PROGRAMFILES(x86))" 计算结果为 ")"。因此,在 msbuild 中似乎不可能使用包含“)”字符的环境变量。我在环境中没有看到其他可以代替的东西。
    • 你有没有尝试转义 ('s?我不是 msbuild 的重度用户,所以我不知道这是否可能
    • 用反斜杠或单引号转义不起作用。但我也不是 msbuild 的重度用户。可能应该问一个新问题逃逸......
    • +1;转义的语法是 $(ProgramFiles%28x86%29) 见msdn.microsoft.com/en-us/library/ms228186%28VS.80%29.aspx
    • this answer 中的产品化评论(实际上已经忘记了答案!)但是如果你想点赞,请点赞this one which was there first
    【解决方案7】:

    我的解决方案是查看“c:\program files (x86)”是否存在,如果存在,假设这是一个 64 位操作系统。否则使用正常的程序文件目录:

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

    我可以这样使用它

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

    【讨论】:

    • 这会在非英语版本的 Windows 上严重崩溃,因为程序文件并不总是称为程序文件。
    • 我认为环境变量 %programfiles% 指向任何语言的程序文件目录。至少在德语中,32 位版本只添加了“(x86)”:tipps-fuer-windows-vista.de/img/Navigation/Navi1.gif 不过不知道日语。
    • 您需要检查一个名为 %ProgramFiles(x86)% 的环境变量。如果存在,那么您使用的是 64 位操作系统,这就是您想要的路径。如果不存在,则使用 %ProgramFiles% 指定的路径。
    • Using Condition="Exists('$(PROGRAMFILES) (x86)')" 在 .net 4.0.21006 的 msbuild 中搜索 C:\Program Files (x86) (x86)
    • @Jedidja 你的意思是当你运行 32 位 版的 MSBuild 时。当您使用Framework64 版本时,它可以工作。已确认适用于 4.0.30319,包括 .NET 4.5 更新 Beta。另请注意,您的观点虽然有效并不能阻止答案实际“工作”,即它确实在 MSBuild 2 和 4 x86 和 x64 上计算 program files (x86)(一直希望将我的 +1 转换为 -1 基于你的信息)
    猜你喜欢
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    相关资源
    最近更新 更多