Powershell and visual studio vcvars32.bat

Posted: July 27, 2008 in Computer and Internet

 

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s