7

I have Visual Studio 9.0 installed but I want to use it manually from PowerShell. It comes with two setup scripts: vcvars32.bat for the 32-bit compiler and vcvars64.bat for the 64-bit compiler. When I open cmd.exe and run one of the scripts, it sets up everything just fine and I can run cl.exe without any problems. When I run one of those setup scripts from PowerShell, though, it doesn't work. The scripts run through fine but trying to run cl.exe afterwards yields a "cl.exe could not be found" error! And looking at the contents of the PATH environment variable after running one of the setup scripts I can see that PATH hasn't actually been modified at all.

So it seems as if the batch files ran from PowerShell maintain their own environment variables state which goes away as soon as the batch file terminates. So is there a way to run batch files from PowerShell and have those batch files affect the actual environment variables of the current PowerShell session? Because that is what I need. All that is done by vcvars32.bit and vcvars64.bit is setting up environment variables after all but it only seems to work from cmd.exe, not from PowerShell.

Andreas
  • 9,245
  • 9
  • 49
  • 97

2 Answers2

9

You should use InvokeEnvironment script to do that. Check its man page:

Invoke-Environment <path_to_>vsvars32.bat

You can furhter generalize this by determining OS bits and crafting the vsvars<OsBits>.bat.

Example:

PS C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools> $env:INCLUDE -eq $null
PS C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools> $true
PS C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools> Invoke-Environment .\vsvars32.bat
PS C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools> $env:INCLUDE
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE;C:\Program Files (x86)\Windows Kits\10\include\10.0.10586.0\ucrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.10586.0\shared;C:\Program Files (x86)\Windows Kits\10\include\10.0.10586.0\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.10586.0\winrt;
majkinetor
  • 8,730
  • 9
  • 54
  • 72
  • Thanks, but it doesn't seem to work. I added it to my profile as described in your `README.md` but still it can't find the `Invoke-Environment` command. When calling the script using a fully qualified path it finds the script but doesn't seem to run the batch script that I pass as the argument because there is no output and it also doesn't set the environment variables correctly. – Andreas Apr 04 '16 at 11:40
  • You doht have to do all that. Just copy/paste the function in your active shell. I used the function on number of projects so it works. It doesn't have an output, to see if it worked check if variables are present in `$Env:` – majkinetor Apr 04 '16 at 11:52
  • Still doesn't work. What is `VS100COMNTOOLS` in your example? Is this an environment variable? It isn't set here. The `vsvarsXXX.bat` scripts are in `C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin` here. – Andreas Apr 04 '16 at 12:00
  • Why don't you just go in that folder you mentiond and execute `Invoke-Environment vsvars64.bat` ? – majkinetor Apr 04 '16 at 12:22
  • I've tried that too, of course, but it doesn't work. It just prints and does nothing. And the environment variables stay the same. Could the problem be related to the fact that I'm still using PowerShell 1.0? – Andreas Apr 04 '16 at 12:29
  • It shouldn't be. Script is v1.0 compatible. I just added you example above. – majkinetor Apr 04 '16 at 12:36
  • Ok, now it's working. I forgot the ".\" prefix. Thanks a lot! Although I'm still puzzled that PowerShell really doesn't have an "in-house solution" for such a trivial thing... – Andreas Apr 04 '16 at 12:40
  • It is off-topic to Powershell TBH. `cmd.exe` is just another shell to Posh, should it support `bash` variables too ? – majkinetor Apr 04 '16 at 12:41
  • Yes, I agree but since both are Microsoft technologies there should be some way to use them together since *.bat scripts are so very very common. There should be a way to integrate them transparently into PowerShell. $0.02 – Andreas Apr 04 '16 at 13:33
  • For me I was able to get the command I wanted into scope pretty quickly by running `.\setup.ps1` as https://github.com/majkinetor/posh/blob/master/README.md says, and then sourcing the profile with `. $PROFILE`. Then `gcm -Module MM_Admin` – solstice333 Feb 25 '21 at 02:04
  • A word of warning since this is like the canonical answer on how to do this: the caveat is it it copies over *all* environment variables which can have unexpected results. Alternative would be to e.g. first call `cmd /c set` and then after doing the same with the batchfile figure out which variables were added/changed and only copy those, since the chances are high only those are the ones effectively set by vcvarsall.bat. – stijn Apr 21 '21 at 19:15
  • Game changer: Visual Studio 2019 ships with a new Launch-VsDevShell.ps1 script that does the job. – vlabatut May 19 '22 at 08:24
0

I don't have Visual Studio at hand, but the batch scripts most likely just set variables for the current session. Running them from PowerShell won't do you any good, because they'll be launched in a child CMD process and change the process environment of that process, but not of the parent (PowerShell) process.

I suspect you need to translate the variable definitions to PowerShell, e.g.

set PATH=%PATH%;C:\some\where
set FOO=bar

becomes

$env:Path += ';C:\some\where'
$env:FOO = 'bar'

Write the translated definitions to a .ps1 file and dot-source that file in your PowerShell session:

. C:\path\to\vcvars.ps1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Hmm, rewriting those batch scripts for PowerShell is of course something I'd like to avoid. Is there really no way to run a batch script within the PowerShell context so that it can modify the PowerShell environment variables? – Andreas Apr 04 '16 at 11:20
  • It is possible. Check my answer – majkinetor Apr 04 '16 at 11:23
  • That runs the batch script, echoes the CMD environment, parses the output and then creates corresponding variables in the PowerShell environment. That's not exactly "running a batch script within PowerShell, so that it can modify the PowerShell environment", but perhaps close enough. – Ansgar Wiechers Apr 04 '16 at 11:39