powershellmsbuildwdk

How to apply EWDK's SetupBuildEnv.cmd to running powershell session


I am using EWDK and msbuild to build some drivers.

I have a build.cmd file that works.

call <EWDK root>/BuildEnv\SetupBuildEnv.cmd
cd <working directory>
msbuild /t:build /p:...

Calling this file from PowerShell works

& build.cmd

I want to write it natively in PowerShell so I won't have a mix of languages.

I tried running it with PowerShell

& <EWDK root>/BuildEnv\SetupBuildEnv.cmd
& msbuild /t:build /p:...

And the build failed because none of the environment variables set in SetupBuildEnv.cmd were kept in the PowerShell session that called the script. I can't re-write SetupBuildEnv.cmd as it comes with the SDK package so this is the only .cmd script which PowerShell should call.

I'd like to have msbuild.exe called directly in PowerShell.

Is there anyway to make this work?


Solution

  • Batch/cmd scripts called from PowerShell run in a new process (cmd.exe). Environment variables set by a batch script (using the set command) don't persist when the cmd.exe process ends, so the PowerShell parent process can't access them.

    As a workaround, create a helper batch script that calls SetupBuildEnv.cmd and then outputs the current values of all environment variables. This output can be captured by the PowerShell script which can then set the environment variables of the PowerShell process accordingly, so msbuild called from PowerShell will inherit them.

    The helper script doesn't need to be a separate file, it can be a cmd.exe /c one-liner, as in the following code sample:

    $envBlockFound = $false
    
    cmd /c 'call "<EWDK root>\BuildEnv\SetupBuildEnv.cmd" & echo ###EnvVars### & set' | ForEach-Object {
        if( $envBlockFound ) {
            $name, $value = $_ -split '='
            Set-Item env:$name $value
        }
        elseif( $_.StartsWith('###EnvVars###') ) {
            $envBlockFound = $true
        }
    }
    
    # uncomment to verify env vars
    # Get-Item env:
    
    msbuild /t:build /p:...