I was skimming through the msdn blogs and saw this post
http://www.agileprogrammer.com/dotnetguy/archive/2007/11/22/23853.aspx
As I had the same problem a few months back when first starting using PowerShell I thought I’d post my solution to it here, as I think it is more general. It can take any bat file’s environment and hook into PowerShel
And it will work with all version of Visual Studio (at least those you might still use)
First the function I can call from any shell (32 or 64 bit) to get the environment for the proper version of VS.
1: function vc([string]$str = "2008")
2: {
3: $path = ""
4:
5: $64bit = !(gv PSHOME).Value.ToLower().Contains("syswow64")
6: $HKLM = "HKLM:\SOFTWARE"
7: if ($64bit)
8: {
9: $HKLM = "HKLM:SOFTWARE\Wow6432Node"
10: }
11:
12: if ($str.contains("9") -or $str.contains("2008"))
13: {
14: $path = (gp "$HKLM\Microsoft\VisualStudio\9.0\Setup\VC").ProductDir
15: $path = $path + "\vcvarsall.bat"
16: }
17: elseif ($str.contains("8") -or $str.contains("2005"))
18: {
19: $path = (gp "$HKLM\Microsoft\VisualStudio\8.0\Setup\VC").ProductDir
20: $path = $path + "\vcvarsall.bat"
21: }
22: elseif ($str.contains("71") -or $str.contains("2003"))
23: {
24: $path = (gp "$HKLM\Microsoft\VisualStudio\7.1\Setup\VC").ProductDir
25: $path = $path + "\vcvarsall.bat"
26: }
27: elseif ($str.contains("7") -or $str.contains("2002"))
28: {
29: $path = (gp "$HKLM\Microsoft\VisualStudio\7.0\Setup\VC").ProductDir
30: $path = $path + "\vcvarsall.bat"
31: }
32: elseif ($str.contains("6") -or $str.contains("98") -or $str.contains("1998"))
33: {
34: $path = (gp "$HKLM\Microsoft\DevStudio\6.0\Products\Microsoft Visual C++").ProductDir
35: $path = $path + "\vcvarsall.bat"
36: }
37: if ($path.length -gt 0)
38: {
39: echo "Setting environment for $path"
40: envbat "$path"
41: }
42: }
And then the ugly but functional envbat function which can take any bat file and "steal" its environment and add it to psh.
1: function envbat
2: {
3: $oldenv = @{}
4: $newenv = @{}
5: get-childitem env: | foreach-object { $oldenv[$_.Key] = $_.Value }
6:
7: $cmd, [string]$args = $args
8: cmd /c " `"$cmd`" $args > nul && set " | Foreach-Object {
9: if($_ -match "^(.*?)=(.*)$")
10: {
11: $newenv[$matches[1]] = $matches[2]
12: }
13: }
14:
15: $newenv.Keys |
16: foreach-object {
17: if (!$oldenv.ContainsKey("$_")) {
18: echo "Adding $_"
19: set-item -Path env:$_ -Value $newenv[$_]
20: } elseif ($oldenv[$_] -ne $newenv[$_]) {
21: echo "Changing $_"
22: set-item -Path env:$_ -Value $newenv[$_]
23: }
24: }
25:
26: $oldenv.Keys |
27: foreach-object {
28: if (!$newenv.ContainsKey("$_")) {
29: echo "Removing $_"
30: remove-item -Path env:$_
31: }
32: }
33: }
So there you have it. A quick explanation, it first remember the current psh environment, runs the batch file followed by "set" (line 8) which produces a list of all environment variables from the cmd shell. Walks through and stores those that match the regexp. The rest is just a matter of updating the psh environment with the cmd keys.