如何从MSBuild中调用64位PowerShell执行AfterBuild构建后脚本
该问题的核心触发原因是当前执行构建命令调用的是32位版本MSBuild。32位进程在64位Windows系统上运行时,会默认开启WOW64文件系统重定向机制:此时csproj中配置的$(WINDIR)\system32\WindowsPowerShell\v1.0\powershell.exe路径,会被系统自动重定向到$(WINDIR)\SysWOW64\WindowsPowerShell\v1.0\powershell.exe,也就是32位版本的PowerShell可执行文件。因此无论怎么显式指定system32下的PowerShell路径,只要父进程MSBuild是32位,默认拉起的都是32位PowerShell进程。
可以先执行命令验证当前MSBuild位数:在执行构建的PowerShell会话中运行(Get-Command msbuild).Source,如果返回路径中MSBuild.exe位于Bin目录而非Bin\amd64目录下,即可确认是32位版本。
二选一即可:
方案1:直接调用64位MSBuild执行构建
这是最直接的解决方式。MSBuild 16.3(对应VS2019)的64位版本位于VS安装目录下的MSBuild\Current\Bin\amd64\MSBuild.exe路径,执行构建时使用全路径指定该版本MSBuild即可。此时原有csproj中的PowerShell路径配置无需修改,64位MSBuild进程不会触发WOW64重定向,会正常拉起system32目录下的64位PowerShell执行脚本。
如果使用VS提供的开发者终端,直接启动「x64 本机工具命令提示 for VS 2019」或对应x64版本的开发者PowerShell,终端默认配置的MSBuild就是64位版本。
方案2:保留32位MSBuild,绕过WOW64重定向指定64位PowerShell
如果必须使用32位MSBuild执行构建,可通过Windows提供的Sysnative路径别名访问64位系统目录——该别名是32位进程访问64位System32目录的专用通道,不会触发文件重定向。
将csproj中的配置修改为如下内容即可:
<PropertyGroup> <!-- 32位MSBuild下用Sysnative路径访问64位PowerShell,64位MSBuild下用原System32路径,做兼容判断 --> <PowerShellExe Condition=" '$(PROCESSOR_ARCHITECTURE)' == 'x86' ">$(WINDIR)\Sysnative\WindowsPowerShell\v1.0\powershell.exe</PowerShellExe> <PowerShellExe Condition=" '$(PROCESSOR_ARCHITECTURE)' != 'x86' ">$(WINDIR)\System32\WindowsPowerShell\v1.0\powershell.exe</PowerShellExe> </PropertyGroup> <Target Name="AfterBuild"> <Exec Command="$(PowerShellExe) -NoProfile -ExecutionPolicy Bypass -File .\Run-AfterBuild.ps1" WorkingDirectory="$(OutputPath)"/> </Target>
配置中额外补充了三个执行参数优化稳定性:
-NoProfile:跳过加载用户PowerShell配置文件,避免自定义配置干扰脚本执行-ExecutionPolicy Bypass:临时绕过当前系统的PowerShell执行策略限制,保证脚本能正常运行-File:明确告知PowerShell后续参数为要执行的脚本文件路径,避免参数解析异常
修改完成后重新执行构建命令,查看脚本输出的Is a 64bitsProcess字段,返回True即代表脚本已经运行在64位模式下。
内容的提问来源于stack exchange,提问作者unitrium

