I would like to run an after build script with Powershell. This script needs to be run in 64bits. However, whenever I run msbuild with my .csproj file the script always runs in 32 bits. If I run the same script from the same powershell session where I started the msbuild, the script runs in x64 just fine.
My command:
msbuild .\src\Project.csproj /t:Build /p:Platform='x64' /p:Configuration='Debug'
I thought I could force to use the 64bits version like suggested on this post My target in my .csproj file:
<PropertyGroup>
<PowerShellExe>$(WINDIR)\system32\WindowsPowerShell\v1.0\powershell.exe</PowerShellExe>
</PropertyGroup>
<Target Name="AfterBuild">
<Exec Command="$(PowerShellExe) .\Run-AfterBuild.ps1" WorkingDirectory="$(OutputPath)"/>
</Target>
The beginning of the after build script:
Write-Host $"Is a 64bitsProcess $([System.Environment]::Is64BitProcess)"
When run from msbuild the output is false, and from the session session that launched msbuild but running the script directly outputs true.
MS build version: 16.3
64-bit vs. 32-bit processes see separate, bitness-specific directories as C:\Windows\System32
.
Therefore, when launched from a 32-bit process, $(WINDIR)\System32\WindowsPowerShell\v1.0\powershell.exe
refers to the 32-bit version of PowerShell.
However, there is a virtual[1] SysNative
directory that allows 32-bit processes to access the 64-bit System32 directory:[2]
$(WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe
For the sake of completeness: For the inverse, i.e. to allow 64-bit processes to access the 32-bit System32 directory, use the (non-virtual) SysWOW64
directory.[3]
[1] When enumerating the child directories of C:\Windows\System32
, no SysNative
entry shows up. However, using it as part of a path, e.g. C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe
, transparently targets the otherwise-invisible-to-32-bit-processes 64-bit System32 directory.
[2] Note that this virtual directory is visible to 32-bit processes only. From inside a PowerShell session, a bitness-agnostic way to refer to the 64-bit SYSTEM32 directory would be:
"$env:windir\" + ('SysNative', 'System32')[[Environment]::Is64BitProcess]
[3] 32-bit processes see this directory too, which for them is the same as $(WINDIR)\System32
.