-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Issue Description
We have a command-line set of tools written in JavaScript (nodeJS) which launch msbuild. Our command line tool is launched via yarn.
Some tools like Yarn will spawn nodeJS via CreateProcess and pass an environment block that contains duplicated environment variables, e.g:
See how the same environment variable is set twice, with different casing.
Windows doesn't do any checking of environment variables being duplicated in CreateProcess so the node.exe process gets created with the two names. Then in our case, MSBuild gets launched from within node.exe, which later launches CL.exe and other build tools.
The Azure DevOps CI pipeline sets NPM_CONFIG_CACHE
(all caps), while yarn will add the lowercase npm_config_cache
to the environment block when a process is launched via child_process.exec()
. See https://github.com/actions/virtual-environments/blob/b47ba413c9bd9411407b8a5cf18e2c14ea8bda78/images/win/scripts/Installers/Install-NodeLts.ps1.
As a result of this, we are hitting an error in our CI because MultiTaskTool is probably putting variables in a case-insensitive dictionary and doesn't expect to find the same variable twice:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(375,5): error MSB6001: Invalid command line switch for "CL.exe". System.ArgumentException: Item has already been added. Key in dictionary: 'NPM_CONFIG_CACHE' Key being added: 'npm_config_cache' [D:\a\1\s\vnext\Common\Common.vcxproj]
Steps to Reproduce
nodeJS file: test.js
console.log(process.env);
child_process.execSync("path_to_msbuild/msbuild.exe myproj.vcxproj");
myproj.vcxproj, just a regular C++ project
in packages.json
add an entry e.g.
"run": "test.js"
in cmd, set NPM_CONFIG_CACHE
then run yarn run
. See that the console.log in test.js shows the variable duplicated, and see that the task to launch CL breaks with an error similar to the above.
Expected Behavior
Build doesn't break
Actual Behavior
Build breaks :)
Analysis
Arguably System.Diagnostics.Process
should sanitize its environment variables, but I'm not sure if that is fixable without introducing breaking changes so that's why I'd like msbuild to guard against this.
Versions & Configurations
all versions