Suppose I'm working in a system that wants to execute something in a workflow step, but I want it to do nothing instead.
Unlike the slightly-related question Dummy command in windows cmd, I'm not in any sort of shell (that I'm aware of). I can only point to an executable and provide parameters.
Is there anything in a typical Windows installation that can be executed as a do-nothing placeholder and returns 0 as its exit code?
I could install a dummy script, but I'd rather avoid doing that to maintain some portability.
C:\Windows\System32\cmd.exe /D /C ""
If there's no shell, then %SYSTEMROOT% is likely not available. For a typical, out-of-the-box installation, the above path is expected. Otherwise, customize to fit your environment.
From the help text:
/C Carries out the command specified by string and then terminates
. . .
/D Disable execution of AutoRun commands from registry (see below)
Following up /C with "" executes nothing. Invoking /D prevents any default scripts from running.
Finally, this returns 0, so it won't interrupt the workflow.
Related
i'm trying to make a batch script for running my Java files. I've found out that there is no way to prevent auto-closure of a batch script(except using pause keyword, tho it just waits for key press). I've also discovered that starting a new window will cause only main windows to close, not the new one too so i want a way that the command SET /P file=Java file: is executed in the new window(I got the new window by using the start keyword. Is there any way to accomplish this without downloading other softwares? this is the code i came up with yet:
cd "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\programs\java programmes"
set /P file=Java file to execute:
java %file%^.jar
start
I guess you're looking for that :
cd "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\programs\java programmes"
start cmd /V:ON /K "#set /P "file=Java file to execute: " && java -jar !file!^.jar"
EDIT: Using expansion with /V and use of /K instead of /C to keep the cmd windows open.
Explanations : To launch a console process in another windows and keep it open after the end of this process console we launch another cmd process with the start command. We use /V:ON to use delayed expansion by default, meaning modified variables (like the one we prompt, %file%) will be expanded on the fly with ! (so !file! instead of %file%). We use /K to tell to this cmd process to not close when provided commands end. To this cmd process, we provide the following commands :
#set /P "file=Java file to execute: "
This one will ask for the jar filename (without extension) to launch.
The # means "do not echo the command itself on the console stdout" for a nice display.
java -jar %file%^.jar
This one launch the java interpreter (JVM) with the filename of a jar file to execute through the -jar parameter, filename build from the previous prompt and the .jar extension. The ^ here escapes the ., it seems not useful here but maybe your script/env requires it.
We link the both commands with && which means : _if left command from && is successful (it exits with ERRORLEVEL 0) then execute the right command from &&.
The Anaconda command prompt looks like normal windows command prompt and its start menu shortcut traces back to the cmd.exe file on windows in the C:\Windows\System32 directory, so I know it is just an instance of the command prompt with certain other characteristics or features. I am curious as to what all these other aspects are.
When I click on properties of the "Anaconda Prompt" shortcut, the target is "%windir%\System32\cmd.exe" /K" C:\ProgramData\Anaconda3\Scripts\activate.bat C:\ProgramData\Anaconda3 so it has some extra arguments. In those arguments is the difference between opening a vanilla command prompt and an Anaconda.
Breaking down these commands, the /k option appears to be described here and here to mean run the command and return to the prompt, although those references refer to a lower case /k.
The next argument points to a bat file to activate an Anaconda script. Then it passes a path to a directory called "Anaconda3". I am fairly certain the path it passes as the final arg means it wants this path to be accessible as if it were in the user or system path environmental variable. Python.exe (Python 3) is in this directory, as well as a _conda.exe and an important Scripts folder, so if we don't have our python in the system or user path, this is how it is found, I am fairly certain.
Back to the .bat file, this does a lot of things. I always though bats were binaries, because of how they acted on the system, but they're really just like Bash Scripts for Windows. They are human readable and mine is as follows:
#set "_args1=%1"
#set _args1_first=%_args1:~0,1%
#set _args1_last=%_args1:~-1%
#set _args1_first=%_args1_first:"=+%
#set _args1_last=%_args1_last:"=+%
#set _args1=
#if "%_args1_first%"=="+" if NOT "%_args1_last%"=="+" (
#CALL "%~dp0..\condabin\conda.bat" activate
#GOTO :End
)
#REM This may work if there are spaces in anything in %*
#CALL "%~dp0..\condabin\conda.bat" activate %*
:End
#set _args1_first=
#set _args1_last=
This .bat calls another .bat, "conda.bat", in a nearby directory with it's own code:
#IF NOT DEFINED _CE_CONDA (
#SET _CE_M=
#SET "CONDA_EXE=%~dp0..\Scripts\conda.exe"
)
#IF [%1]==[activate] "%~dp0_conda_activate" %*
#IF [%1]==[deactivate] "%~dp0_conda_activate" %*
#SETLOCAL EnableDelayedExpansion
#IF DEFINED _CE_CONDA (
#REM when _CE_CONDA is defined, we're in develop mode. CONDA_EXE is actually python.exe in the root of the dev env.
FOR %%A IN ("%CONDA_EXE%") DO #SET _sysp=%%~dpA
) ELSE (
#REM This is the standard user case. This script is run in root\condabin.
FOR %%A IN ("%~dp0.") DO #SET _sysp=%%~dpA
IF NOT EXIST "!_sysp!\Scripts\conda.exe" #SET "_sysp=!_sysp!..\"
)
#SET _sysp=!_sysp:~0,-1!
#SET PATH=!_sysp!;!_sysp!\Library\mingw-w64\bin;!_sysp!\Library\usr\bin;!_sysp!\Library\bin;!_sysp!\Scripts;!_sysp!\bin;%PATH%
#SET CONDA_EXES="%CONDA_EXE%" %_CE_M% %_CE_CONDA%
#CALL %CONDA_EXES% %*
#ENDLOCAL
#IF %errorlevel% NEQ 0 EXIT /B %errorlevel%
#IF [%1]==[install] "%~dp0_conda_activate" reactivate
#IF [%1]==[update] "%~dp0_conda_activate" reactivate
#IF [%1]==[upgrade] "%~dp0_conda_activate" reactivate
#IF [%1]==[remove] "%~dp0_conda_activate" reactivate
#IF [%1]==[uninstall] "%~dp0_conda_activate" reactivate
#EXIT /B %errorlevel%
As I expected, when I called the activate.bat file in an ordinary (admin) command prompt, it turned into an Anaconda prompt with the "(base)" prefix before my current path you get when you click the startup shortcut. (base) C:\Users\User>. Interestingly, doing this only seems to work in the regular command prompt, not Git Bash, not WSL, not even Powershell, though there is a separate Powershell launcher that works. In its properties, it has the target:
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -NoExit -Command "& 'C:\ProgramData\Anaconda3\shell\condabin\conda-hook.ps1' ; conda activate 'C:\ProgramData\Anaconda3' "
And if you run the ps1 file (a powershell like script), it has the same effect of putting you into the conda environment, because you can run the 'conda' command and help instructions appear.
Here is the ps1 code.
$Env:CONDA_EXE = "C:/ProgramData/Anaconda3\Scripts\conda.exe"
$Env:_CE_M = ""
$Env:_CE_CONDA = ""
$Env:_CONDA_ROOT = "C:/ProgramData/Anaconda3"
$Env:_CONDA_EXE = "C:/ProgramData/Anaconda3\Scripts\conda.exe"
Import-Module "$Env:_CONDA_ROOT\shell\condabin\Conda.psm1"
Add-CondaEnvironmentToPrompt
Anyway that's just kind of the background context, which I learned in the last few hour researching, because I wanted to do my homework. I wanted and want to know is what Conda is doing in Windows when you open the Command Prompt through Anaconda. I'm pretty certain it is doing two main things: setting the path to include the C:\ProgramData\Anaconda3 directory, for the session, and activating it's base environment or any other virtual environment you tell it to launch that you may have created through it at some point, but does it do anything else of note?
I ask this not just because I am curious about what's really going on (I am), but I was also hoping to work with Conda in Git Bash and WSL, terminals I really like. I can currently use Conda's Python with them (the only Python on my machine) as it seems to exist independent of the program that installed it and manages packages for it, but I was specifically hoping to use the all the Conda environment management tools inside Git Bash or WSL. After thinking about it, I now don't believe this is possible. From a naive user perspective, one sort of assumes they can run any program anywhere, and that makes sense or would have made sense before we had sub-systems and systems within systems, but from a more aware point of view, Anaconda was installed for Windows and inside the C:\ProgramData\Anaconda3 directory are .exe and .bat files, not Linux/WSL compatible binaries and .sh or .bash files. It's like trying to run Windows_OS>Linux subsystem>Windows_file_again, but it doesn't work like that. WSL and Git Bash don't even have the same path structure somehow. Am I right in my thinking so far?
I enjoy Git Bash and WSL more than Powershell or cmd and I use them a lot for GCC and git. I do most of my coding in VS Code and launch these terminals there. I suppose at best I could install conda for git bash or wsl if such a thing existed, but even then it might not be able to talk to my main Conda or share environments. Otherwise I could either trying using venv for an environment, as that appears to work in these shells through python, or just use the normal command prompt to do everything if I really want to use Conda.
Am I right in my assessments?
Thanks for sticking with me! To get good at something, you have to get to the point where it's all plainly obvious, otherwise you run the risk of being lost and confused at a time you least want to be.
Edit: Now that I'm back at it, I rediscovered my original hurdle: the fact couldn't use Conda's command prompt straight from the VS Code or how to activate it once I booted the normal command prompt. Now I know about the .bat startup script at least and could in theory activate it that way each time, but it's kind of awkward, or I could launch a prompt externally and navigate to my working directory, but that's clumsy too. I forgot that this was my first blocker, and on a related note I had similar issues with x64 Native Tools (a Visual Studio based command prompt). I wondered what that was as well, why it looked like an independent terminal but I couldn't launch it in VS Code.
For WSL, yes you are right. Running the conda that you installed for windows would be the same as trying to run any other program that you installed for windows -> it will fail because the binaries are not compatible. You would probably be able to install the linux version there, but as you pointed out, that is not what you want.
For git bash, the solution is more simple than you might think. You can set it up so that you can "talk"to your windows installed conda. Yes, you will need to have the equivalent setup to what you have already discovered for cmd and powershell, but conda already has everything you need to set it up.
Assuming your installation is at C:\Users\foo\miniconda3\, from your git bash, do:
/c/Users/foo/miniconda3/Scripts/activate
conda init bash
this will modify your bash_profile to automatically set up conda for use from git bash
Some clarifications:
I now don't believe this is possible. From a naive user perspective, one sort of assumes they can run any program anywhere, and that makes sense or would have made sense before we had sub-systems and systems within systems, but from a more aware point of view, Anaconda was installed for Windows and inside the C:\ProgramData\Anaconda3 directory are .exe and .bat files, not Linux/WSL compatible binaries and .sh or .bash files. It's like trying to run Windows_OS>Linux subsystem>Windows_file_again, but it doesn't work like that. WSL and Git Bash don't even have the same path structure somehow
WSL, as you have pointed out, is a subsystem and, since wsl 2 runs a real linux kernel. It naturally follows that, as you have said, it is not possible to run windows binaries from it.
Git bash however, is not a subsystem at all. Instead, it is a port of bash for windows. That means when you are in your git bash, you are still within your windows environment. Only the syntax for paths and commands is different (see above commands I have provided), but you are still in the same system.
If you look at the file
C:\Users\foo\miniconda3\Scripts\activate
you will also see that it is a normal .sh script that calls conda.sh at
C:\Users\a-fjochhe\miniconda3\etc\profile.d\conda.sh
So ana/miniconda does indeed come with a set of sh scripts that you can use from a bash terminal in Windows
I'm actually trying to run an application as another user and while it works really nicely in a cmd.exe prompt, it doesn't always work if I go with the Windows Run prompt (it actually depends on what application I'm trying to run).
For example, this works fine both from cmd.exe or from W-Run prompt (using either Windows XP or Windows 7):
runas /user:ME regedit.exe
While this only works in a cmd.exe prompt (it does ask for my password in both cases but it does nothing after that if launched from W-Run on either WinXP or W7):
runas /user:ME services.msc
It's actually kind of inconsistent, with cmd it always works but with Windows Run, it's really unreliable and random.
Any ideas where there is such a difference? To get around the problem, I'm actually using batch files to launch applications as another user and then just type the batch file full path in Windows Run prompt. It does ensure reliability but I still would like to know if I'm doing something wrong.
cmd /k "runas /user:ME ""regedit.exe"" && exit"
The "problem" with runas are
It needs all the command as only one argument, so if you are running something with arguments you have to enclose all the command in quotes, and if the command includes its own quotes, they need to be escaped.
It is designed to call .exe files (well, windows valid executable files).
This two options should handle your program start
runas /user:ME "cmd.exe /c \"start services.msc\""
runas /user:ME "mmc.exe %systemroot%\system32\services.msc"
In the first case, it is using the ability of cmd.exe to find the adecuated executable to run the .msc file. In the second case, it directly calls the adecuated executable to handle the .msc file.
For your batch files, instead of cmd /k .... & exit, you can directly use cmd /c ... that will close the console when the command finishes.
[Context: I'm trying to create a shortcut to a .bat file with a relative "Start in" path as roughly described here and here.]
cmd.exe supports the /c switch. According to the documentation, this should cause it to "carry out the command and then terminate."
But the switch seems to be ignored when the command is a .bat file.
For example, if you create a shortcut with the following Target (to a normal, non-bat command):
C:\Windows\System32\cmd.exe /c "START /d C:\temp\ notepad.exe test.txt"
Everything works as expected: Notepad opens and the console (shell) disappears. But if you replace the command above with a .bat file instead, like so:
C:\Windows\System32\cmd.exe /c "START /d C:\temp\ C:\test.bat"
(where test.bat contains only "notepad.exe test.txt") Notepad opens as before but the console sticks around like an unwanted friend. Why? And more to the point, How do I make it go away?
UPDATE: I know I can use wscript, as in this solution, but then I lose the option of having a custom icon (I'm stuck with the default .vbs icon).
The start command begins a new process for the batch file. The original cmd.exe then terminates, but leaves the new process, which hangs around because it's waiting for notepad.exe to terminate.
Change your bat file contents to:
start "" notepad.exe test.txt
Then your batch file will not wait for notepad to exit before continuing execution.
Another thing to try:
C:\Windows\System32\cmd.exe /c "START /d C:\temp\ C:\test.bat & exit"
The nuclear option would be to write a small program in the (compiled) language of your choice that launches the .bat file and then exits. Then you can give it a custom icon, and make it do whatever you like.
You might also take a look at Autoit from http://autoitscript.com as an alternative to batch. - the Run() command can do this kind of thing with better predictability. Since it makes an executable you can link this from a shortcut directly. You can also do a whole lot more of course, like run as a different user, insert delays or handle errors, that are hard to do with batch.
You don't need the full kit, just the Aut2EXE folder from the download will do.
BTW, build your exes without UPX compression as that leads to AV false positives.
I'm a little late but here is the answer.
The documentation for start states:
Syntax
START "title" [/D path] [options] "command" [parameters]
If command is an internal cmd command or a batch file then the command
processor is run with the /K switch to cmd.exe. This means that the
window will remain after the command has been run.
If start is used to execute a batch file, the opened cmd instance wont close.
You could also use call instead.
call C:\test.bat
I'm porting a Linux tool-set that makes frequent use of shell functions to provide certain functionality. These functions are automatically sourced when you start a new shell and include things like changing the working directory, which is nigh impossible with stand-alone programs because child processes can't change their parent's environment.
For example, there is a function cdbm which changes the working directory to one that was previously bookmarked. Now I want to do the same on Windows, but I'm stuck with cmd.exe. As far as I understand the scripts could be ported to jscript, vbscript or plain batch, which shouldn't be a problem. But how do I make sure they automatically get sourced on startup and live in the shell's environment?
According to help cmd:
If /D was NOT specified on the command line, then when CMD.EXE starts, it
looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
either or both are present, they are executed first.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
As a test, in regedit I created a new key in the HLM branch shown above called "AutoRun" with the string value "echo Hi". When I started a new instance of cmd I got:
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
Hi
C:\Users\Username>
You could put in the name of a script to run instead (I would put in a fully specified path to the script or one with a environment variable in it like "%HOMEPATH%\scripts\scriptname" (including the quotes in case there are spaces in the name).
Edit:
The registry key has some side effects. One example is help. If I have the echo command above, for example, in the AutoRun when I type help vol I get a "Hi" right above the help text. Doing vol /?, though doesn't do that.
You can set either of the following registry keys to a batch file or other executable to run that program when CMD is started:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
A batch file should be able to change the current directory of the executing CMD process with the CD command, as it doesn't run as a subprocess. You can disable the autorun behaviour by supplying /D as a switch to CMD.
See CMD /? for more details.
Since cmd doesn't allow you to define functions in global scope, I'm a little at a loss to understand what exactly you're trying to achieve by auto-sourcing a script at startup. I tend to include a batch file directory in my path where you can put batch files I regularly need.
Look at cygwin.