Use PowerShell for Visual Studio Command Prompt - windows

In a serious intiative to migrate all my command line operations to PowerShell, I would like to avoid using the old fashioned command console for anything. However, the Visual Studio Command prompt has various environment variables and path settings not found in the default command prompt. How could I create a 'Visual Studio PowerShell' with those same settings?

You can use for example this script to import Visual Studio command prompt environment, see the examples in the script documentation comments, e.g. for Visual Studio 2010:
Invoke-Environment '"%VS100COMNTOOLS%\vsvars32.bat"'
Having done that in the beginning of a PowerShell session (from your profile or manually), you get what you ask for in this PowerShell session.
Or you can use the solution provided by Keith Hill in this answer.

have a look at PowerConsole

PowerConsole has been incorporated into NuGet http://nuget.codeplex.com/. You get PowerShell inside Visual Studio and a package management system.

I use this script that I call Initialize-VisualStudio.ps1, i call it in my profile with dot source, to set the environment variables need it, in my actual session:
param([switch]$ArquitectureX86)
if($ArquitectureX86)
{ $arq= "x86"}
else
{ $arq="x64"}
pushd 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC'
cmd /c "vcvarsall.bat $arq&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])";
}
}
popd

What I do is create a simple cmd batch command script that looks like this:
call "%VS80COMNTOOLS%vsvars32.bat"
powershell
Then I create a shortcut that invokes this through cmd. The shortcut target looks like:
%windir%\System32\cmd.exe /k "SetupPSBuildEnvironment.cmd"
If you want the console to look like the powershell console, just modify the Layout to your liking in the shortcut properties.

First, check the contents of this folder:
C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances/
There'll be another folder in it with a name consisting of hex digits (e.g. 2a7a9ed6, but that will vary for different MSVC versions). I'll refer to it as <instance_id>.
Then run from PS:
Import-Module 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'
Or you can create a shortcut with the following target:
<path to your powershell.exe> -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'}"
Obviously, drop -arch=x64 if you need x86 toolset.
Works for me on Windows 10 with MS Build Tools 16.9.5 and PowerShell 5.1.19041,7.1.3

Related

How can I open a solution file from powershell?

I'm new to powershell and I'm looking to create a powershell script to open two different solution files with two different versions of visual studio. I have the commands for opening up the different visual studio versions, but not sure how to open the solutions with each one. Here is what I have so far.
$vs19 = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe"
$vs19WorkDir = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\"
$vs15 = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"
$vs15WorkDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\"
Start-Process $vs19 -WorkingDirectory $vs19WorkDir
Start-Process $vs15 -WorkingDirectory $vs15WorkDir
Although not super obvious at first glance, the devenv command line reference mentions:
When specifying a solution or project, the first argument is the name of the solution file or project file, including file path.
With this in mind, I tried the following against Visual Studio 16 (2019):
& "path\to\devenv.exe" "path\to\a\solution.sln"
and it opened the solution in question, so you should be able to do it with:
Start-Process $vs19 -WorkingDirectory $vs19WorkDir -ArgumentList "c:\path\to\solution.sln"
I wrote a Powershell script to solve this problem. It was inspired by #Mathias R. Jessen's answer. You can find it on this Github gist
EDIT:
I shared the gist on Reddit as well and it turns out that there are much cooler and intuitive ways of achieving this on PowerShell. Check them out as well.
PS: `The fastest method I've seen so far is by typing *.sln, then hitting Tab and Enter

Running VS 2017 Build Tools in Windows PowerShell

I dislike IDEs, so I installed the VS 2017 Build Tools so I can work via command-line.
The install went fine, and everything works out of Windows CMD, however, PowerShell is much better, and I prefer to use PS. The issue here is that according to MSDN:
The Visual C++ command-line tools use the PATH, TMP, INCLUDE, LIB, and LIBPATH environment variables, and may also use tool-specific environment variables. Because the values of these environment variables are specific to your installation, and can be changed by product updates or upgrades, we recommend that you use vcvarsall.bat or a Developer Command Prompt shortcut instead of setting them yourself. For information about the specific environment variables used by the compiler and linker, see CL Environment Variables and LINK Environment Variables.
I shouldn't set the Environment Variables myself, and that's fine with me, the only issue is that when I run the vcvarsall.bat in PS, no environment variables change. I am new to PS, so I'm guessing that .bat files can't alter session environment variables. If that's the case, then I can't work out of PS. As a side note, the CL and LINK variables never show up, I'll explain below.
I figured I should find out what the variables are. I echoed all my variables to a text file before and after running the batch file, and wrote a short Java program to find anything new, or modified. These are them. As you can see the CL and LINK variables are not present.
How do I solve this issue? I was thinking of writing my own batch file, but if the first one didn't work, why would mine? I didn't see anything on the attached MSDN page, or any links there about how to make this work for PowerShell.
Write a batch file that 1) invokes vcvarsall.bat, and 2) invokes PowerShell, like so (this one is specific to VS 2015):
#CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %*
#start powershell
%* allows us to pass the same arguments to this file as you would to vcvarsall.bat.
PowerShell will then run with the environment block prepared for it. The other way around doesn't work because PowerShell doesn't execute batch files itself -- it relies on cmd to do that, and as a child process, that has its own environment block that doesn't reflect on its parent.
<#
.SYNOPSIS
Invokes the specified batch file and retains any environment variable changes it makes.
.DESCRIPTION
Invoke the specified batch file (and parameters), but also propagate any
environment variable changes back to the PowerShell environment that
called it.
.PARAMETER Path
Path to a .bat or .cmd file.
.PARAMETER Parameters
Parameters to pass to the batch file.
.EXAMPLE
C:\PS> Invoke-BatchFile "$env:ProgramFiles\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
Invokes the vcvarsall.bat file. All environment variable changes it makes will be
propagated to the current PowerShell session.
.NOTES
Author: Lee Holmes
#>
function Invoke-BatchFile
{
param([string]$Path, [string]$Parameters)
$tempFile = [IO.Path]::GetTempFileName()
## Store the output of cmd.exe. We also ask cmd.exe to output
## the environment table after the batch file completes
cmd.exe /c " `"$Path`" $Parameters && set " > $tempFile
## Go through the environment variables in the temp file.
## For each of them, set the variable in our local environment.
Get-Content $tempFile | Foreach-Object {
if ($_ -match "^(.*?)=(.*)$") {
Set-Content "env:\$($matches[1])" $matches[2]
}
else {
$_
}
}
Remove-Item $tempFile
}
$VcVars = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Auxiliary\Build\vcvarsall.bat'
Invoke-BatchFile $VcVars x64
cl hello_world.cpp

How can I use the cl command on PowerShell?

I am unable to use the cl command in PowerShell.
I tried to add the following command to my PowerShell profile to exec vcbuildtools.bat, but PowerShell does not recognize cl command on PowerShell?
&"C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
OS: Windows 10
Just to be clear I'm addressing the asker's issue that cl is not in the PATH even after running this in PowerShell
&"C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
I think this boils down to the issue that batch file can't export variables to PowerShell (also related: this question), as you've found out with vcbuildtools.bat. I think it's because PowerShell invokes a cmd.exe subshell to execute the batch file which changes the environment in the subshell but the changes don't propagate to the parent shell i.e. PowerShell.
Solution 1
One way is to use the fact that subshell inherits the environment from the parent shell. So if you run this in PowerShell, the environment set by the batch file is preserved
cmd.exe /k "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat" `& powershell
Take note of `&. The character has to be escaped because it has a special meaning in PowerShell.
Solution 2
The Pscx module has an Import-VisualStudioVars function which imports environment variables for Visual Studio. An example usage is
Import-VisualStudioVars 2015 amd64
if you're using VS/BuildTools 2015 and compiling 64-bit programs. You can use Pop-EnvironmentBlock to revert the changes. See man Import-VisualStudioVars -full for more information.
Alternatively, Pscx also has an Invoke-BatchFile function that retains environment changes by a batch file. An example usage
Invoke-BatchFile "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
See man Invoke-Batchfile -full for more information.
Notes
To download the up-to-date version of Pscx from PowerShell gallery, you will need PowerShellGet which is shipped with PowerShell 5 and is available as a downloadable installer for PowerShell 3 and 4.
For those with PowerShell 1 and 2, older versions of Pscx is available on Codeplex.
You can use the following function to invoke a cmd.exe shell script (batch file) and persist its environment variables:
function Invoke-CmdScript {
param(
[String] $scriptName
)
$cmdLine = """$scriptName"" $args & set"
& $env:SystemRoot\system32\cmd.exe /c $cmdLine |
Select-String '^([^=]*)=(.*)$' | ForEach-Object {
$varName = $_.Matches[0].Groups[1].Value
$varValue = $_.Matches[0].Groups[2].Value
Set-Item Env:$varName $varValue
}
}
Add this function to your PowerShell profile, and run the batch file using the function:
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
Fortunately, VS 2019 Community now has a Developer PowerShell for VS 2019 command.
The actual command, if you want to see the properties for the shortcut, is rather verbose.
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell 14bbfab9}"
Anyway, I am using this and it adds the right cl.exe to my path, but there is an odd message after running it:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\ostream(750): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
.\hey.cpp(4): note: see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)' being compiled
Another option from PowerShell gallery:
posh-vs
Makes Visual Studio command line tools available in PowerShell. Supports Visual Studio 2017 and 2015.
I also encountered the same problem, type cmd.exe and you'll change control to command line.
PowerShell example
If you want to go back to PowerShell, no problem. Just write exit. As simple as it sounds

Change directory in visual studio command prompt

I want to know what is the command I should execute in the command window of the visual studio 2013, to change directory to:
C/:Users/user/Documents/Visual Studio 2013/Projects/OutlookAddin/publish/<Most_Recent_Version>/OutlookAddin_TemporaryKey.pfx
What is the command I must execute?
Actually, cd cmd works, but in a bit diff like this:
syntax:
cd /d c: or e: etc..
where /d stands for drive
for instance:
cd /d C/:Users/user/Documents/Visual Studio 2013/Projects/OutlookAddin/publish//OutlookAddin_TemporaryKey.pfx
No need for the single or double quote in this case.
Now to execute any type of files for instance simply add '.\' before the executed one.
syntax:
.\OutlookAddin_TemporaryKey.pfx or .\example.exe what so ever
cd does work. However, keep in mind that if the path you're trying to get to has spaces, you need quotes around it (the path). E.g.:
cd "C:\Program Files\Microsoft Visual Studio 10.0" Also, note that the
"Visual Studio command prompt" that is mentioned in Step 6 is not the
"Visual Studio Command Window" - I think this is where the problem
comes from. The command prompt is a separate executable that you can
start by clicking Start, point to All Programs, point to Microsoft
Visual Studio, point to Visual Studio Tools, and then click Visual
Studio Command Prompt. Alternatively, just search "Visual Studio" in
the search bar in the Start menu, and it should show up
Source: Using the Command Window in Visual Studio
First create a file on CMD (COMMAND PROMPT)
1.cd desktop
2.mkdir filename
3.cd filename
4. code .
(It has to be a space between code and the dot to open up the file in visual studio code)
Note: If you just want to open visual studio, then go to CMD and just type in 'code' without the dot.

Change Default Visual Studio Command Prompt Location

How to set the default visual studio command prompt location so that I can go straight to my project's directory instead of using the usual navigation.
For Visual Studio 2017 Command Prompt, you need to set environment variable VSCMD_START_DIR to the directory where you want to end up after the command prompt initializes.
I use this script:
set VSCMD_START_DIR=%1
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
It accepts the directory as the first (and only) argument.
Add it as an external tool to Visual Studio (2008 shown here, should be similar in other versions):
Select "Tools", "External Tools...".
Click Add
Title: &Cmd
Command: cmd.exe
Arguments: /k "c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86
Initial Directory: $(SolutionDir)
Note the arguments come from the "Visual Studio 2008 Command Prompt" shortcut. Yours may vary.
You can can customize the toolbar and add a button for this command as well using "Tools", "Customize...". Open the Tools menu and locate the last External Tool you created and drag it onto the toolbar.
When you click the button, it will open a command prompt in the current solution's root directory.
In Visual Studio 2013,
Right click on "Developer Command Prompt for VS2013" shortcut (which you can find in the "Common7\Tools\Shortcuts" folder from where you installed your VS2013) and choose "Properties",
Change the: "Start in: " directory to your desired location.
Navigate to the "vcvarsall.bat" file. For me the path is:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
Add this line to the bottom of the script:
cd /d "D:\WhereverYouWant"
skol
For Developer Command Prompt for VS 2019 you can set VSCMD_START_DIR environment variable with the following command:
setx VSCMD_START_DIR C:\your-folder
You can put these lines in a batch script (vcvar.bat) located in the directory you want to start with:
#echo off
set VCDIR=%ProgramFiles%\Microsoft Visual Studio 10.0\VC
if not exist "%VCDIR%" set VCDIR=%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\VC
call "%VCDIR%\bin\vcvars32.bat"
Fire a command prompt in this directory, and call vcvar.bat. You now have the VS environment in the command prompt.
Copy Windows Command Processor from "C:\Windows\System32\cmd.exe" and paste to "C:\Your\Project\Directory\cmd.exe"
Edit Visual Studio Command Prompt shortcut by replacing %comspec% with "C:\Your\Project\Directory\cmd.exe" in the Target field.
So the shortcut's Target should look something like: "C:\Your\Project\Directory\cmd.exe" /k ""C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" amd64
this will add a menu entry "my compiler " to each directory giving you access to the command prompt in the directory.
save it as something.reg
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\My Compiler]
[HKEY_CLASSES_ROOT\Directory\shell\My Compiler\command]
#="cmd.exe /k \"C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\vcvarsall.bat\""

Resources