Visual studio 2017 Developer Command Prompt switches current directory - cmd

I am getting weird behavior of "Developer Command Prompt for VS 2017" command line tool. Normally in previous versions of visual studio this script (VsDevCmd.bat) was not messing current directory from where you run it. Now it seems to change it. One simple workflow would be just to start the shortcut "Developer Command Prompt for VS 2017" and it doesn't honor the "Start in" directory:
By any chance anyone seen this issue? It really bugs me because I used to have a shortcut with it and start CMD in my source directory, use TFS/msbuild commands afterwards.

You can set the VSCMD_START_DIR environment variable to have vsdevcmd.bat change to that directory when it finishes. Otherwise it will check if you have a %USERPROFILE%\source directory and change to that (which is what you see).
You can change the "Target" for the "Developer Command Prompt for VS 2017" to something like the following to have change to a particular directory:
%comspec% /k "set VSCMD_START_DIR=C:\temp && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat""
Note that the path to vsdevcmd.bat needs to be put in an additional set of double quotes.
Alternatively, rename or remove the %USERPROFILE%\source directory (Note that this seems to be some kind of new "standard" directory for sources), that will make vsdevcmd.bat honor the "Start In"-value (i.e. "current directory").

:: Some rocket scientist in Redmond made the VS15 VsDevCmd.bat change the cwd; the pushd/popd fixes that.
pushd %CD%
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"
popd
"C:\Program Files (x86)\CruiseControl.NET\server\ccnet.exe" %*

vsdevcmd_end.bat, REM out the line:
cd /d "%USERPROFILE%\Source"
#REM Set the current directory that users will be set after the script completes
#REM in the following order:
#REM 1. [VSCMD_START_DIR] will be used if specified in the user environment
#REM 2. [USERPROFILE]\source if it exists
#REM 3. current directory
if "%VSCMD_START_DIR%" NEQ "" (
cd /d "%VSCMD_START_DIR%"
) else (
if EXIST "%USERPROFILE%\Source" (
cd /d "%USERPROFILE%\Source"
)
)

If I see your quastion in right way that I'm used to work with EntityFramework Core with the help of CMD or PowerShell. For this you should right-click In the Solution Explorer panel then in the context menu, click Open Folder in File Explorer. In the address bar of the file explorer type cmd or powershell, you will start the command line from the project folder.

Related

Batch | Why can't a script running in admin access other scripts? [duplicate]

I have a batch file that is in the same directory as the file I want to xcopy. But for some reason the file is not being found.
I thought that current directory was always where the batch file was located.
I run batch file as administrator. This occurs on a Windows 7 64-bit desktop computer.
Batch file:
#ECHO OFF
XCOPY /y "File1.txt" "File2.txt"
PAUSE
Error:
File not found - File1.txt
0 File(s) copied
Which directory is current working directory on starting a batch file with context menu item Run as administrator depends on User Account Control (UAC) setting for the current user.
This can be demonstrated with following small batch file C:\Temp\Test.bat:
#echo Current directory is: %CD%
#pause
With having selected in User Account Control Settings
Default - Notify me only when programs try to make changes to my computer
Don't notify me when I make changes to Windows settings
and using Run as administrator, Windows uses registry key
HKEY_CLASSES_ROOT\batfile\shell\runasuser\command
This registry key does not contain a default string for executing the batch file. Instead there is the string value DelegateExecute with the CLSID {ea72d00e-4960-42fa-ba92-7792a7944c1d}.
The result is opening a dialog window with title User Account Control and text:
Do you want to allow the following program to make changes to this computer?
Program name: Windows Command Processor
Verified publisher: Microsoft Windows
After confirmation by the user, Windows opens temporarily a new user session like when using on command line RunAs.
In this new user session the current working directory is %SystemRoot%\System32 on executing now the command defined in Windows registry with default string of key
HKEY_CLASSES_ROOT\batfile\shell\runas\command
which is:
%SystemRoot%\System32\cmd.exe /C "%1" %*
Therefore a console window is opened with title C:\Windows\System32\cmd.exe and the 2 lines:
Current directory is: C:\Windows\System32
Press any key to continue . . .
After hitting any key, batch execution finishes which results in closing cmd.exe which results in closing the user session.
But with having selected in User Account Control Settings
Never notify me when
Programs try to install software or make changes to my computer
I make changes to Windows settings
the behavior is different as the user has already elevated privileges.
Now Windows uses directly the command
%SystemRoot%\System32\cmd.exe /C "%1" %*
according to default string of key
HKEY_CLASSES_ROOT\batfile\shell\runas\command
in current user session.
The result is opening a console window also with title C:\Windows\System32\cmd.exe, but displayed in window is:
Current directory is: C:\Temp
Press any key to continue . . .
The current working directory of the parent process (Windows Explorer as desktop) is used for executing of the batch file because no switch to a different user session was necessary in this case.
PA has posted already 2 possible solutions in his answer which I replicate here with a small improvement (pushd with directory in double quotes) and with adding a third one.
Change current directory to directory of batch file using pushd and popd:
pushd "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
popd
This works also for UNC paths. Run in a command prompt window pushd /? for an explanation why this also works for UNC paths.
Use directory of batch file in source and destination specifications:
%SystemRoot%\System32\xcopy.exe "%~dp0File1.txt" "%~dp0File2.txt" /Y
Change working directory to directory of batch file using cd:
cd /D "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
This does not work for UNC paths because command interpreter cmd does not support a UNC path as current directory by default, see for example CMD does not support UNC paths as current directories for details.
The error message is very self explanatory. The file file1.txt is not found.
Because the file name does not include an absolute path, the system tries to find it on the current directory. Your current directory does not contain this file.
Your misconception is that the current directory is not the directory that contains the bat file. Those are two unrelated concepts.
You can easily check by adding this two commands in your bat file
echo BAT directory is %~dp0
echo Current directory is %CD%
you can notice they are different, and that there is a subtle difference in the way the last backslash is appended or not.
So, there are esentially two ways to cope with this problem
either change the current directory to match the expected one
pushd %~dp0
XCOPY /y "File1.txt" "File2.txt"
popd
or specify the full path in the command
XCOPY /y "%~dp0File1.txt" "%~dp0File2.txt"
For the sake of completeness and obscurity, I add another workaround, confirmed as working under Windows 8.1 and expected to work elsewhere, as it relies on documented functionality:
You can change the runas command definition keys
HKEY_CLASSES_ROOT\batfile\shell\runas\command and
HKEY_CLASSES_ROOT\cmdfile\shell\runas\command into
%SystemRoot%\System32\cmd.exe /S /C "(for %%G in (%1) do cd /D "%%~dpG") & "%1"" %*
Which results in the bat or cmd file starting in its containing directory when started using the runas verb, respectively the "Run as Administrator" menu entry.
What the additions to the original command exactly do:
cmd /S strips away first and last (double) quote in command string after /C
for %%G in (%1) do enumerates its single entry, the %1 argument,
making it available for expansion as %%G in the loop body; the letter is arbitrary but some may be "reserved"
%%~dpG expands to the drive and path of %%G, the ~ tilde stripping away quotes if present, which is why we add them back explicitly
cd /D changes both the drive and directory to its argument, and finally
& runs the second command "%1" %* regardless of success of the first one.
You can use pushd which will even support UNC paths, but a stray popd would land any script in the system32 directory, not a behavior I would be fond of.
It should be possible to do this for the exefile entry as well, but frankly, I'd rather live with the inconsistency than to attempt this on my system, as any error there could break a lot.
Enjoy defeating the security mechanics of your operating system :)

When using Keyboard Shortcut : Command is being invoked from C:\Windows\system32 instead of Current Directory

My target is to create a folder named _Misc in the current folder using shortcut Ctrl+Alt+M
I created a shortcut in desktop.
In the properties of the shortcut, went to the Shortcut tab and put the following values
Target: C:\Windows\System32\cmd.exe /k mkdir _Misc
Start in: %CD%
Shortcut Key: Ctrl+Alt+M
Now, when I press Ctrl+Alt+M in any folder, for example: D:\Test it says
Access is denied.
C:\Windows\system32>
So I think the the command mkdir _Misc is being invoked from C:\Windows\system32 instead of D:\Test
What do I need to do?
That approach can never work. The shortcut key of a shortcut file can be used anywhere. For example Windows executes the Target command line even when Ctrl+Alt+M is pressed while viewing this page in browser. Which directory should be the current directory on browser having input focus?
A solution is using the Send to context menu which is customizable by adding shortcuts to folder %APPDATA%\Microsoft\Windows\SendTo on Windows Vista / Server 2008 or any later Windows version. The directory is %UserProfile%\SendTo on Windows XP / Server 2003.
Create a batch file in a directory you want with following lines:
#echo off
if "%~1" == "" exit
if not exist "%~1" exit
setlocal EnableExtensions DisableDelayedExpansion
set "Directory=%~1"
if "%Directory:~-1%" == "\" goto MakeDirectory
if not exist "%~1\" for %%I in ("%~1") do set "Directory=%%~dpI" & goto MakeDirectory
set "Directory=%Directory%\"
:MakeDirectory
if not exist "%Directory%_Misc\" md "%Directory%_Misc"
endlocal & if exist "%Directory%_Misc\" cd /D "%Directory%_Misc"
Line two and three result in exiting batch file and started command process if the batch file is called without any argument or with a string which is not an existing directory or file.
The next lines make it possible to Send to a full qualified directory or file name to the batch file. Directory or file names with relative paths are not really supported by this batch file.
Windows Explorer passes a full qualified directory name without a backslash at end to the batch file. But in case of argument one is a string ending with a backslash, the batch file knows at this execution step that first argument references a directory which really exists and so can immediately continue with creating the subdirectory.
The argument can reference an existing directory or an existing file in case of string of argument one is not ending with a backslash as on being invoked from Windows Explorer context menu Send to. For that reason the batch file next checks if the argument string references a file in which case it uses the file path as directory path.
Then the subdirectory _Misc is created if that directory does not already exist. This works even with a UNC path starting with \\ServerName\ShareName\ passed to the batch file.
Last the temporary environment is deleted using endlocal resulting in deletion of environment variable Directory and restoring initial current directory as it was pushed on stack on execution of command setlocal. For that reason the last command line contains two commands: endlocal to restore default environment and an if for checking existence of subdirectory _Misc and making this directory the current directory after execution of endlocal.
Please note that cd /D fails by default if a UNC path was passed to the batch file.
This batch file must be called from a shortcut file created in %APPDATA%\Microsoft\Windows\SendTo on Windows Vista and later versions of Windows with a name you like to see in Send to context menu and with an icon you prefer for this context menu item.
The Target in shortcut properties must be:
%SystemRoot%\System32\cmd.exe /K "Path to batch file\BatchFileName.bat"
Shortcut property Start in can be empty in which case %USERPROFILE% is used by Windows Explorer, or there is an existing directory specified which is used as default current directory in case of last line fails because of subdirectory _Misc could not be created because of missing required permissions.
The started command process keeps running because of option /K after finishing execution of the batch file. The command process would be closed on using option /C instead of /K.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~1
cd /?
echo /?
endlocal /?
exit /?
for /?
goto /?
if /?
md /?
set /?
setlocal /?

Navigate to a specified path in cmd file

Now I am currently in C:\WINDOWS\system32>
I need to mention it in the cmd file
How can I navigate to a specific path in cmd file.
Please provide the lines.
#echo off
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
cd "C:\hadoop-2.6.0-src"
mvn package -Pdist,native-win,docs -DskipTests -Dtar
pause
popd
This is my cmd file.The mvn command is not getting executed in the specified path. two separate command prompts is getting opened but it is not running and get closed immediately
Thanks in advance.
PUSHD Change the current directory/folder and store the previous folder/path for use by the POPD command
#echo off
setlocal
pushd "C:\hadoop-2.6.0-src"
cd
pause
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
cd
pause
popd
Additional cd commands (without parameters) should display the current drive and directory.
Read more

mklink fails from Visual Studio

I have next pre build event:
cmd /C mklink /D /J "$(ProjectDir)SomeDir" "$(ProjectDir)"
This is expanded in(copied from MSBuild output):
cmd /C mklink /D /J "C:\Dir-1\Dir-2\other-dirs-here\SomeDir" "C:\Dir-1\Dir-2\other-dirs-here\"
When running the build with this build event the symbolic link is not created, but when I copy exactly the expanded output of Visual Studio in command line the link is created.
Do you know why?
EDIT: I have administrator rights on the computer. Both Visual Studio and Command Prompt have "Administrator" on top
Found the problem - the previous command in the build event was:
$(ANDROID_HOME)/tools/android.bat update project my-project-settings
and for some weird reasons prevented all commands after it to run...

Execute batch file. How to call .bat file, visual studio command prompt and change directory in opened command prompt window

#echo off
echo copy masterDB file from one directory to another one
copy "C:\dir\dbfile" "C:\dir1\dbfile"
cd c:\lvsdir
call lvsrun.bat
timeout /t 180
start %comspec% /k ""C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86
cd C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
MSTest /testcontainer: C:\testdir\test.dll
I want to do via a batch file to copy a db file from one directory to another one(which executes correct), then should start lvsrun.bat file, which should start lvs server,
and then to open visual studio command prompt in a new window, change directory in opened command prompt to test directory and run test file. Problem occurs when i call lvsrun.bat, and it stucks there. New vs command prompt can't be opened. And having problem with changing directory in opened vs command prompt and run test file. Code above doesn't really work
You've asked two questions here. You should split them up and ask them as two separate SO questions.
Q1. Why is my batch file never getting past call lvsrun.bat?
A1. Because call will not return until the batch file it is calling has exited. If you want to launch lvsrun.bat and continue execution immediately, use start.
copy "C:\dir\dbfile" "C:\dir1\dbfile"
cd c:\lvsdir
start "" "%comspec%" /k lvsrun.bat
Q2. Why doesn't the new command window I launch run my test file?
A2. Your batch file will only control its command window. If you launch another command window, that one is on its own, you can't "send" commands to it. But you could instead run the test in the current window rather than launching another:
:: Use "call" here to run vcvarsall.bat to set up the environment in this process
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
cd C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
MSTest /testcontainer: C:\testdir\test.dll
Or you could make a second batch file just for running the test. For example, let's call it runtest.bat, and give it those exact same lines:
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
cd C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
MSTest /testcontainer: C:\testdir\test.dll
which would then get called from your original batch file either synchronously:
call runtest.bat
or asynchronously:
start "" "%comspec%" /c runtest.bat

Resources