How can I change the default starting directory of cmd.exe on Windows 10 when opened using the key sequence Super-x c (by "Super" I mean the windows key, whatever its name is)? I can change the the link in the start menu by modifying the entry in
"%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk"
with visual basic or otherwise, but it doesn't effect the normal way I open the prompt which is the key sequence above. I would just like to change the working directory to the value of an environment variable I set as "%HOME%".
As #JosefZ showed in his comment, the directory to look in was "%LOCALAPPDATA%\Microsoft\Windows\WinX\Group3". Just to wrap up the question, I was able to modify the shortcuts with a simple batch script,
Basically, just the following, which will modify the starting directory of the link in the start menu, as well as the win-x links for user/admin.
:: preamble stuff
set "startup=%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools"
call :modifyLink "%startup%\Command Prompt.lnk"
call :modifyLink "%LOCALAPPDATA%\Microsoft\Windows\WinX\Group3\01 - Command Prompt.lnk"
call :modifyLink "%LOCALAPPDATA%\Microsoft\Windows\WinX\Group3\02 - Command Prompt.lnk"
:EOF
:modifyLink
set tscript="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%.vbs"
echo.Set sh = CreateObject("WScript.Shell") > "%tscript%"
echo.Set shortcut = sh.CreateShortcut("%~1") >> "%tscript%"
echo.shortcut.WorkingDirectory = "%HOME%" >> "%tscript%"
echo.shortcut.Save >> "%tscript%"
cscript /nologo "%tscript%"
del "%tscript%"
Related
I need some help: I want to create an explorer context menu option(while right clicking on a folder) for my program to run it as administrator from the context menu by using this .bat file:
#ECHO OFF
:: Choose the correct command processor for the current operating system
SET _cmd=
:: Variable to add shortcut to menu entry (NT only,
:: since COMMAND.COM cannot echo an ampersand)
SET _=
ECHO.%COMSPEC% | FIND /I "command.com" >NUL
IF NOT ERRORLEVEL 1 SET _cmd=command.com /e:4096
ECHO.%COMSPEC% | FIND /I "cmd.exe" >NUL
IF NOT ERRORLEVEL 1 SET _cmd=cmd.exe
IF [%_cmd%]==[cmd.exe] SET _=^&
:: Create a temporary .REG file
> %TEMP%.\DEFOPEN.REG ECHO REGEDIT4
>>%TEMP%.\DEFOPEN.REG ECHO.
:Print
ECHO Adding "Explorer context menu option" entry
>>%TEMP%.\DEFOPEN.REG ECHO [HKEY_CLASSES_ROOT\Directory\shell\ourprog]
>>%TEMP%.\DEFOPEN.REG ECHO #="%_%Add to Hot Backup (A.A.T Anti-Ransomware)"
>>%TEMP%.\DEFOPEN.REG ECHO.
>>%TEMP%.\DEFOPEN.REG ECHO [HKEY_CLASSES_ROOT\Directory\shell\ourprog\command]
>>%TEMP%.\DEFOPEN.REG ECHO #="java -jar C:\users\Tamir Naaman\Desktop\A.A.T-Anti-Ransomware.jar -backup \"%%L\"
>>%TEMP%.\DEFOPEN.REG ECHO.
:: If neither COMMAND.COM nor CMD.EXE then skip this step
IF [%_cmd%]==[] GOTO Merge
:: Merge the temporary .REG file
:Merge
START /WAIT REGEDIT /S %TEMP%.\DEFOPEN.REG
:: Delete the temporary .REG file
DEL %TEMP%.\DEFOPEN.REG
:: Ready
GOTO End
:: Clean up variables and quit
:End
SET _cmd=
SET _=
and I got this error message after I tried to click the option in the context menu:
error message
The registry picture:
Registry picture
The registry picture:
Registry picture
I just noticed that the default value is not set, how can i fix my code?
Can you help me find the problem in my batch file?
Thank you for your help!
Registry settings for 'Directory Shell Context Menu Command' to be executed As Administrator
For a context menu command to be executed As Administrator(Elevated) you have to put the command under the special verb RunAs like: [HKEY_CURRENT_USER\Software\Classes\Directory\shell\runas\command]
For directories, this special verb is usually unused, but you can never be sure about that, so using is not recommended at all.
The alternate recommended option is to use Static Cascading Menus, which has been introduced starting from Windows 7. With them, the context menu can be fully isolated with its own private RunAs verb.
A sample registry script leveraging Cascading Menus would be
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade]
"ExtendedSubCommandsKey"="Directory\\shell\\AATCascade"
"MUIVerb"="A.A.T Anti-Ransomware"
"HasLUAShield"=""
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade\shell\runas]
"HasLUAShield"=""
"MUIVerb"="Add to Hot Backup"
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade\shell\runas\command]
#="java.exe -jar \"C:\\Users\\Tamir Naaman\\Desktop\\A.A.T-Anti-Ransomware.jar\" -backup \"%V\""
You have to make sure that the location of java.exe is defined in the PATH environment variable or specify the full path to java.exe
The advantage of Cascading Menus is that you can add as many commands as you need (with custom verbs other than RunAs) and keep all of them under the root cascading menu resulting in a more user friendly and much cleaner context menu.
Under each sub menu there could be only one RunAs verb, So if there are more menu item command that needs elevation you have to elevate them by other means. And PowerShell can used for that task: PowerShell.exe -Command Start-Process "PathToExecutable" 'ExecutableParameters' -Verb RunAs
It is even possible to create nested cascading menus to keep the menu items more organized when you want add many more sub items and each sub menu can have its own RunAs verb.
After you have done testing the registry script then you can move on to the next step and adopt the registry script for importing from a batch file.
Embedding the registry script into a batch file
Three methods can be used each with its own pros and cons:
Converting the registry script to individual REG.EXE ADD commands. The advantage is that you don't need to escape the backslash(\) and double quotes(") like what is seen in registry scripts and it is more flexible in configuring the registry settings at runtime e.g. Determining the the location of the supporting files at runtime and adjusting the registry setting accordingly. But the conversion process is tedious and error-prone. Although there are tools out there than can automate the task and quickly convert a registry script to a batch file.
Writing the registry script to a temporary file at runtime using the echo commands like what you have done(with errors and mistakes of course). It provides some level of flexibility in adjusting the registry script at runtime with the help of environment variables, but you have to preserve the escaped syntax of the original registry script and also be careful about special characters in batch and escape them too. For small scripts this is not a problem but for bigger ones it gets out of management very quickly.
The batch script:
#echo off
(
echo REGEDIT4
echo,
echo [HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade]
echo "ExtendedSubCommandsKey"="Directory\\shell\\AATCascade"
echo "MUIVerb"="A.A.T Anti-Ransomware"
echo "HasLUAShield"=""
echo [HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade\shell\runas]
echo "HasLUAShield"=""
echo "MUIVerb"="Add to Hot Backup"
echo [HKEY_CURRENT_USER\Software\Classes\Directory\shell\AATCascade\shell\runas\command]
echo #=^"java.exe -jar \"C:\\Users\\Tamir Naaman\\Desktop\\A.A.T-Anti-Ransomware.jar\" -backup \"%%V\"^"
)>"%TEMP%\DEFOPEN.REG"
:: First try to import the registry script by REG.EXE to avoid unnecessary elevation if possible.
:: In case all the base keys are HKEY_CURRENT_USER no elevation is required.
REG IMPORT "%TEMP%\DEFOPEN.REG" 2>nul || REGEDIT /S "%TEMP%\DEFOPEN.REG"
del "%TEMP%\DEFOPEN.REG"
The last method is to copy paste the registry script at the end the following batch script. The advantage is that no special handling is required and the reg script can used as is. The disadvantage is that the registry script is static and batch script will not have control over the contents at runtime, it will be imported as it is.
Self Importer BAT/REG Script:
:: SelfImporter BAT/REG Script
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "TIME="
set "id=%TIME: =0%"
call :getBatFileInfo #f0 #nx0
set "id=%#nx0%.%id:~0,2%%id:~3,2%%id:~6,2%%id:~-2%"
set "RegFile=%TEMP%\RegImport.%id%.reg.tmp"
(
echo REGEDIT4
echo,
type "%#f0%"
)>"%RegFile%" && (
echo Importing registry script...
REG IMPORT "%RegFile%" 2>nul || REGEDIT /S "%RegFile%"
del "%RegFile%"
)
pause
goto :EOF
:getBatFileInfo <f0> <nx0>
set "%~1=%~f0" & set "%~2=%~nx0" & exit /b
<End of batch script>
Windows Registry Editor Version 5.00
The rest the registry script goes here
.
.
And at last you can just save your batch scripts with .CMD extension and forget about COMMAND.COM
To get the information I'm assuming you wanted into the registry your script should probably look a little more like this:
#ECHO OFF
( ECHO REGEDIT4
ECHO(
ECHO [HKEY_CURRENT_USER\Software\Classes\Directory\shell\ourprog]
ECHO #="Add to Hot Backup (A.A.T Anti-Ransomware)"
ECHO(
ECHO [HKEY_CURRENT_USER\Software\Classes\Directory\shell\ourprog\command]
ECHO #="java -jar \"C:\\Users\\Tamir Naaman\\Desktop\\A.A.T-Anti-Ransomware.jar\" -backup \"%%V\""
ECHO()>"%TEMP%\DEFOPEN.REG"
REGEDIT /S "%TEMP%\DEFOPEN.REG"
DEL "%TEMP%\DEFOPEN.REG"
It is your responsibility to ensure that the java command without specifying a full path will work fine in the target environment.
You will note that I have used the user key, because using the a key for every user on the PC is unnecessary especially when the jar file is located within a specific users profile tree
I am trying to start the default application for a file, wait for it to complete, and then continue with my batch file. The problem is that start, when used below simply creates another command prompt window with the example.doc in the title bar. I can use call instead of start, but then call does not wait for the program to finish before going to the next line. It appears that start needs to have an executable name and will not work with the default application system in windows.
Any ideas how I can make this happen without having to hardcode the windows application in the batch file as well?
set filename=example.doc
start /wait %filename%
copy %filename% %filename%.bak
How do I start the default application for a file, wait for completion, then continue?
It appears that start needs to have an executable name and will not work with the default application system in windows.
start, when used below simply creates another command prompt window with the example.doc in the title bar
start /wait %filename%
The above command won't work because %filename% is used as the window title instead of a command to run.
Always include a TITLE this can be a simple string like "My Script" or just a pair of empty quotes ""
According to the Microsoft documentation, the title is optional, but depending on the other options chosen you can have problems if it is omitted.
Source start
Try the following command instead:
start "" /wait %filename%
Alternative solution using the default open command
Any ideas how I can make this happen without having to hardcode the
windows application in the batch file as well?
One way is to use assoc and ftype to get the default open command used for the file then execute that command.
The following batch file does that for you (so no hard coding of windows applications is needed).
Open.cmd:
#echo off
setlocal enabledelayedexpansion
set _file=example.doc
rem get the extension
for %%a in (%_file%) do (
set _ext=%%~xa
)
rem get the filetype associated with the extension
for /f "usebackq tokens=2 delims==" %%b in (`assoc %_ext%`) do (
set _assoc=%%b
)
rem get the open command used for files of type filetype
for /f "usebackq tokens=2 delims==" %%c in (`ftype %_assoc%`) do (
set _command=%%c
rem replace %1 in the open command with the filename
set _command=!_command:%%1=%_file%!
)
rem run the command and wait for it to finish.
start "" /wait %_command%
copy %_file% %_file%.bak 1>nul
endlocal
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
assoc - Display or change the association between a file extension and a fileType
enabledelayedexpansion - Delayed Expansion will cause variables to be expanded at execution time rather than at parse time.
for - Conditionally perform a command several times.
for /f - Loop command against the results of another command.
ftype - Display or change the link between a FileType and an executable program.
start - Start a program, command or batch script (opens in a new window).
variable edit/replace - Edit and replace the characters assigned to a string variable.
Simply use the filename directly as command, unless that filename is a batch file, in which case use call.
In a batch file invocation of a GUI subsystem executable is blocking, unlike for an interactive command.
Use the start command when you don't want blocking execution.
There is a subtle point about “default application”, namely that a file type can have a registered default application for the graphical shell, e.g. its “Open with…”, without having an assoc/ftype association, or different from that association.
I'm not entirely sure of which registry entries are used for this. I've always had to look it up and research it each time. As I recall it's not well-documented.
But hopefully you're OK with just the assoc/ftype scheme.
A further subtle point about “default application”: on the laptop I'm writing this on the ftype association for text files is to open them in Notepad:
[H:\forums\so]
> assoc .txt
.txt=txtfile
[H:\forums\so]
> ftype txtfile
txtfile=%SystemRoot%\system32\NOTEPAD.EXE %1
[H:\forums\so]
> _
And this is what the graphical shell (Windows Explorer) will do.
But cmd.exe looks inside files, and if it finds an executable signature then it tries to run the text file as an executable, even in Windows 10:
[H:\forums\so]
> echo MZ bah! >oops.txt
[H:\forums\so]
> oops.txt
This version of H:\forums\so\oops.txt is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.
[H:\forums\so]
> _
I have been trying to create a shortcut to launch a batch file one folder up from the shortcut location.
I have been able to do this using and intermediate batch file in the same folder as the shortcut as follows:
Intermediate.bat:
#echo off
FOR %%V IN ("%~dp0..\") DO set curdrv=%%~dpV
start "" %curdrv%Oneup.bat
And the shortcut target is:
%windir%\system32\cmd.exe /c Intermediate.bat
and the 'Start in' is left blank.
This way I can move these folders anywhere on the drive or another drive and the shortcut still works.
However, I would like to leave out the Intermediate.bat file and launch the Oneup.bat directly. I tried:
%windir%\system32\cmd.exe /c FOR %%V IN ("%~dp0..\") DO set curdrv=%%~dpV && start "" %curdrv%Oneup.bat
in the Target of the shortcut, but it doesn't work.
Is there some trick to getting this to work?
Thanks
I think I found the answer:
%windir%\system32\cmd.exe /c start "" "..\Oneup.bat"
This is placed in the shortcut target with start in being left empty.
I have a feeling I should be able add a directory to the PATH environment variable on an application-lifetime basis, but I can't find out how to do this. Is it possible to add a parameter to a Windows shortcut that appends a directory to the current value of PATH for use by the application being linked?
As explained here: http://www.labs64.com/blog/2012/06/set-environment-variables-in-windows-shortcut/
you can do it without a bat file too.
Set Target to e.g.:
C:\Windows\System32\cmd.exe /c "SET path=%path%&& START /D ^"C:\Program Files (x86)\Notepad++^" notepad++.exe"
To avoid see the command prompt for a split second before it close again, you should set
Run: Minimized
on the Shortcut tab
(Tested on Windows 7, Windows 10)
Let the shortcut execute a batch file (.cmd), that
Sets the environment variable
execute the app
You use "START" to execute the app, this will start the app in another process, but it will copy the environment. You do not wait for the app to finish.
Now you can exit the batch file.
Should look like this:
#echo off
set path=%path%;C:\My Folder
start "Window Title" "Path to my exe"
Linking directly to a batch file spawns an annoying console that you probably want to avoid. Here's a work-around. The simpler solution is to use the "Start Minimized" option in your link, but on Windows 7 you'll see a momentary console light up your task bar.
start.bat:
#echo off
IF "%1" == "" GOTO Error
IF "%2" == "" GOTO Error
IF NOT EXIST %2 GOTO Error
SET PATH=%1;%PATH%
start %2
GOTO End
:Error
echo Problem!
pause
:End
shortcut target:
MyPath = "C:\MyApp"
Set shell = WScript.CreateObject("WScript.Shell")
cmd = "start.bat " & MyPath & " MyApp.exe"
shell.Run cmd, 0, false
Set env = Nothing
Set shell = Nothing
You can do this with PowerShell easily. PowerShell exposes environment variables using the $env: prefix. For example, I wanted to launch TeamSQL with custom JAVA_HOME and PATH environment variables, so I could connect to a PostgreSQL database. TeamSQL depends on JDK / OpenJDK for this purpose.
First, I downloaded pre-built OpenJDK and extracted the ZIP archive with 7-Zip.
Next, in PowerShell, I ran the following:
$env:JAVA_HOME='C:\Users\TrevorSullivan\Downloads\openjdk\jdk-11.0.2\'
$env:PATH += ';%JAVA_HOME%\bin'
# Launch TeamSQL
& C:\Users\TrevorSullivan\AppData\Local\Programs\TeamSQL\TeamSQL.exe
Store that PowerShell code in a .ps1 file, and you can run it with PowerShell. Because child processes inherit the environment variables from the PowerShell session, your program is good to go.
When I open cmd on my laptop it is defaulting to the F: drive. This is troubling me does anyone know how it got that way or how to get it back to where it opens to the C: drive by default?
Use the command
C:
To change to the drive C. It would of course work for any drive letter.
Very minor nit: if you're using Windows 7 you don't need the cmdhere powertoy, it's built in to Explorer.
You just navigate to a directory in Windows Explorer then hold down the shift key and right click. "Open command window here" is one of the selections on the context menu.
When it comes to opening cmd.exe in a specific directory, I just create a shortcut to cmd.exe and then in the shortcut properties I set "Start in:" to the drive/directory I want it to start in.
Using a shortcut allows me to customize the cmd.exe windows depending on what I'm using it for. For normal file editing/viewing I use a 180x60 window and appropriate font, but when I want to read/search log files I have a shortcut that opens a 260x100 window with a smaller font. That way I can view most long log file lines without having to use the horizontal scroll.
http://blog.stevienova.com/2007/04/08/change-your-default-cmd-prompt-path/
Sometimes, your path when you go to start->run, CMD will be something
you don’t want. In active directory or on an NT domain, sometimes your
default home path might be a network drive. This isn’t so good when
you are offline or drop offline after being online. The CMD prompt is
set to a place where you can’t get to.
To change the path, you can edit the registry (at your own risk)
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USERSoftwareMicrosoftCommand Processor] “Autorun”=”c:”
This will change the path to your c: drive.
I believe it defaults to %HOMEDRIVE%\%HOMEPATH% so if you can muck about with those environment variables that might be an option. I can't edit these environment variables on my company's network, so I had to use the AutoRun to change it to something sane.
quick answer: cmd /k c:
long answer to make it "automagical":
http://windowsxp.mvps.org/autoruncmd.htm
In RegEdit.exe I created a String:
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
The value I used for AutoRun was "D:"
On the start screen / menu, type in "cmd", right-click it and select "Open File - Location".
In the opened window, right-Click on "Command Prompt" icon, select "Properties", and edit the "Start In" property to your desired path. I used "C:\" as an example
If you are opening it from a shortcut change the working dir for the shortcut.
In addition to the other answers, there's a nice powertoy for XP called "open command window here." It adds an option to your right-click context menu when you click inside a folder to open a command window using that directory as the starting path.
http://www.microsoft.com/windowsxp/Downloads/powertoys/Xppowertoys.mspx
I ran into a similar issue where cmd would always open up in a particular directory (annoying when running scripts which invoke cmd). The best way to deal with this is to edit your autorun settings. Raymond Chen has a nice article about this here:
http://blogs.msdn.com/oldnewthing/archive/2007/11/21/6447771.aspx
The summary is that when you start a command shell, it checks the autorun registry key, and executes the commands stored there. The registry keys it checks are:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
Some answers already mentioned AutoRun as a solution.
But that can be very dangerous, as the AutoRun entry will be executed for any new cmd.exe instance (only pipes ignore the AutoRun).
A simple expample that fails:
cd /d E:\myPath
FOR /F "delims=" %%Q in ('dir') do echo - %%Q
With AutoRun=C:, this shows the content of the current path of drive C:
You can still use AutoRun, but it should be a batch script, that checks if it was called interactive, by FOR/F or by drag&drop.
#echo off
REM *** To enable this script, call it by <scriptName> --install
setlocal EnableDelayedExpansion
REM *** ALWAYS make a copy of the complete CMDCMDLINE, else you destroy the original!!!
set "_ccl_=!cmdcmdline!"
REM *** The check is necessary to distinguish between a new cmd.exe instance for a user or for a "FOR /F" sub-command
if "!_ccl_:~1,-2!" == "!comspec!" (
REM ***** INTERACTIVE ****
REM *** %1 contains only data, when the script itself was called from the command line
if "%~1" NEQ "" (
goto :direct_call
)
endlocal
doskey /macrofile="%~dp0\cmdMacros.mac"
echo ********************************************************************
echo * AutoRun executed from "%~f0"
echo * Macros loaded from "%~dp0\cmdMacros.mac"
echo ********************************************************************
cd /d C:\myPath
) ELSE (
REM *** Called by a FOR command, by an explorer click or a drag & drop operation
REM *** Handle PROBLEMATIC Drag&Drop content, if necessary
endlocal
)
exit /b
:direct_call
if "%~1" == "--install" (
reg add "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v "AutoRun" /t REG_SZ /d "%~f0"
exit /b
)
if "%~1" == "--show" (
reg query "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun
exit /b
)
if "%~1" == "--remove" (
reg DELETE "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun /f
)
exit /b