I wanna ask you how to execute multiple commands in start, but, I know how to, but I cannot set a variable for example:
start cmd.exe /k "set ram=1024 & java -Xmx%ram%M"
but it doesnt work
If you really want to run it in a batch file, see below, also as for your if statement comment, enclose in "" to ensure you do not catch unwanted whitespace
:
#echo off
if "%input%"=="start" set "ram=1024" & goto java
Goto :eof
:java
start "" java -Xmx%ram%M"
Related
I need to search through a file and get some result but using a new window.
If I run the "for" loop with out the START command am getting the correct results, but when I open the process in a new windows the results are wrong.
Start "" /Min Cmd.exe /C For /f "tokens=1,2,3" %%a in (file.txt) do (
set value1=%%a
set value2=%%b
)
echo. %value1%
echo. %value2%
This is what am getting as a result:
%a
%b
I'm not sure what you expect.
Possibility 1) - You want the ECHO statements to run in your parent batch script, displaying the result of the FOR /F command that was run in another window.
This simply cannot be done. You cannot execute a FOR command in one window, and process the iterations (the DO portion) in another window.
Also, if you manage to run the entire FOR loop in another window, any variables you set will be totally separate from your parent batch environment. Your parent batch script will not have access to the variables from the other window.
Possibility 2) - You want everything (including the ECHO statements) to run within the new Window.
This is possible, but awkward, and can also be problematic depending on the file content.
You must put the entire "script" as a single line that gets passed as a parameter to the CMD /C command. Quoting and escaping can quickly become tricky. The entire line will be parsed in a single pass, so you would need the child window to use delayed expansion. But FOR loops will corrupt content if delayed expansion is enabled and the content includes !. You cannot toggle delayed expansion ON and OFF within the loop because the new window has a command line context, not batch, so the SETLOCAL ENABLEDELAYEDEXPANSION command does not work.
I don't see what possible purpose this serves, but the following will run, with the constraint that values containing ! will be corrupted. I had to add a PAUSE command so that you have an opportunity to see the output.
start "" /min cmd.exe /v:on /c "(for /f "tokens=1,2" %%a in (file.txt) do #set "value1=%%a"&set "value2=%%b")&echo(!value1!&echo(!value2!&pause"
When you use a FOR loop in a bat file you need to double the %%. From the command line (which is your case... since you are starting a new instance of CMD.exe) only use single %. Change both occurrences of %%a to %a and %%b to %b and it will work.
I'm creating a simple command line using Batch for a personal project. However, whenever I try to execute a batch file in it, the command line closes as soon as the batch file completes. Why is that, and how can I fix it?
This is the relevant bit of source (also an SSCCE):
#echo off
:loopstart
set /p comnd=%cd%^>
%comnd%
goto loopstart
I have comments but must give you an answer, so couple things:
The /p option in Set generates a prompt for user input, so it's waiting for an answer but you are not handling any user response.
You have set up an infinite loop with the goto at the end (but that doesn't necessarily cause CMD window to close).
Rem out the goto at end and add a pause and you should be able to track down the problem.
EDIT: New answer per user's comments ---------------------------------------
Use call in this bat and exit /b at end of each bat you're running from this prompt.
:loopstart
set /p comnd=%cd%^>
call %comnd%
goto loopstart
I am trying to create a batch file to restart multiple computers from a TXT file. Everything works fine as long as the /c "comment here" parameter has no spaces. If I pass "Testing" as the comment, I get "Testing" in the pop-up for the restart, as expected. If I pass "Testing spaces" as the comment, I still only get "Testing" in the pop-up. With #echo off, I have verified the comment retains the spaces when it is passed to VBS, so I think the problem is that I am running through an "invisible.vbs" script to prevent another CMD window from opening and hanging the original BAT script.
I would like to be able to have a final command run similar to:
shutdown /r /m \\127.0.0.1 /t 120 /c "Your computer will shut down for maintenance tasks in two minutes"
Any help with this would be greatly appreciated!
The essential part of restart.bat:
for /f "tokens=1-3" %%c in (%FilePath%) do WScript /nologo "%windir%\myscripts\invisible.vbs" "shutdown /r /m \\%%c /t %delay% /c %message%"
I have also tried adding extra quotes around %message% with no success:
for /f "tokens=1-3" %%c in (%FilePath%) do WScript /nologo "%windir%\myscripts\invisible.vbs" "shutdown /r /m \\%%c /t %delay% /c "%message%""
The invisible.vbs script (found on StackExchange):
CreateObject("Wscript.Shell").Run "" & WScript.Arguments(0) & "", 0, False
Any help would be greatly appreciated!
EDIT: Using your third method suggested, I am getting a script error:
Script: C:\Windows\myscripts\invisible.vbs
Line: 1
Char: 46
Error: The system cannot find the file specified
Code: 80070002
Source: (null)
EDIT 2: I just tried the first method also, and I now get a vbscript echo pop-up with the correct command that I wish to be sent, but the command is not sent. I am far from a programmer, and the only VBS I have used is stuff I have found online. I do appreciate the help you have offered so far, but I still can't get this to work.
You can not do it. The logic behind the Arguments object in WScript seems to remove quotes.
So, i can think in at least three alternatives
1) The most simple: use another character as an indicator of a quote and replace it with quote in the vbs script
cmd code : cscript myscript.vbs "shutdown /r /m \\%%c /t %delay% /c '%message%'"
vbs code : WScript.CreateObject("WScript.Shell").Run replace(WScript.Arguments(0),"'",""""), 0, False
The only problem with it is at some point, probably, you will need to use the placeholder character as a real character.
2) The most complex: use wmi to retrieve the current process id and from here retrieve the original command line of the script. A lot of code, if interested, here at StackOverflow there are some nice samples.
3) The easy, fast, and unusual. Use environment variables. Save the command into a variable and pass the name of the variable to the script. From it, retrieve the variable contents and use it
cmd code : set "runVar=shutdown /r /m \\%%c /t %delay% /c "%message%""
wscript //nologo "%windir%\myscripts\runInvisible.vbs" runVar
vbs code : With WScript.CreateObject("WScript.Shell") : .Run .ExpandEnvironmentStrings("%" & WScript.Arguments(0) & "%"), 0, False : End With
cmd code or bat code:
wscript //nologo invisible.vbs "hello world" 0
somehow the zero on the end, causes the part between quotes being seen as one argument still
I have a framework where I can only run stuff through PowerShell, but I need to run batch file commands. I'm trying to run a PowerShell Script, something like:
cmd /c blah
for blah I want to do something like:
set myPath = c:\theDir && if not exist %myPath% mkdir %myPath%
This will not work the first time I run it as the set command doesn't seem to take affect until the second line. Any ideas?
This is because cmd evaluates variables when a line is parsed, not when it's run. To get the latter behaviour you'll have to use delayed expansion:
cmd /c /v:on "set MyPath=C:\theDir&& if not exist "!myPath!" mkdir "!myPath!"
Note also that you must not have spaces around the = in a set, otherwise you're creating a variable name with a space at the end (which is to say, your approach would never have worked anyway).
for %d in (some\path and\maybe\another\one) do #if not exist "%d" md "%d"
You can also define the delayed expansion before you run multiple commands. That way you would not have to open a new CMD instance:
Setlocal EnableDelayedExpansion
set say=Hello && echo !say! && echo Done!
You can also do like this
SET _KillElevated=1& SET _KillWithGrace=1
I like to have a final PAUSE in my *.bat scripts so I can just double click on them in Windows explorer and have the chance to read the output. However, the final PAUSE is an annoyance when I run the same script from the command line.
Is there any way to detect whether we are running the script from a command prompt (or not) and insert the PAUSE (or not) accordingly?
(Target environment is Windows XP and greater.)
Update
I've managed to compose this from Anders's answer:
(((echo.%cmdcmdline%)|find /I "%~0")>nul)
if %errorlevel% equ 0 (
set GUI=1
) else (
set CLI=1
)
Then, I can do stuff like this:
if defined GUI pause
#echo off
echo.Hello World
(((echo.%cmdcmdline%)|find /I "%~0")>nul)&&pause
...NT+ only, no %cmdcmdline% in Win9x probably.
As pointed out by E M in the comments, putting all of this on one line opens you up to some edge cases where %cmdcmdline% will escape out of the parenthesis. The workaround is to use two lines:
#echo off
echo.Hello World
echo.%cmdcmdline% | find /I "%~0" >nul
if not errorlevel 1 pause
I doubt that there's a distinction, because I think it just starts a command prompt and then runs the bat when you double click on it.
However, if you make shortcuts to the bat files and go to Properties and add in an extra argument (something like "/p") in the "Target" field, then you could check for the presence of that argument at the end of the script and pause if it is set. Then, running from the shortcut would cause it to end in a pause and running from command line wouldn't.
I was hoping the answer by #Anders would work in its own .bat file. Unfortunately, it does not for me. Based on #DarinH's comment, perhaps it does for some. The script below should work for all, but requires an extra parameter.
The key lies in the %CmdCmdLine% environment variable, which I imagine might be a bit different for a few edge cases.
PauseIfGui.bat
#echo off
if "%~1" == "" ((echo.%CmdCmdLine%)|"%WinDir%\System32\find.exe" /I "%~0")>nul && pause & exit /b
((echo.%CmdCmdLine%)|"%WinDir%\System32\find.exe" /I "%~1")>nul && pause
This accepts one optional parameter: the full path of calling script. If no params are passed, it runs the same as #Anders script.
AnyOtherFile.bat
#echo off
call PauseIfGui.bat %~f0
If opened from Explorer (i.e. double-clicking) , AnyOtherFile.bat will pause. If called from a command prompt, it will not.