Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pausing a batch file when double-clicked but not when run from a console window?

Is there a way for a batch file (in this case, running on Windows XP) to determine whether it was launched from a command line (i.e. inside a console window) or launched via the shell (e.g. by double-clicking)?

I have a script which I'd like to have pause at certain points when run via the shell, but not when run at a command line. I've seen a similar question on SO, but am unable to use the same solution for two reasons: first, whether or not it pauses needs to be dependent on multiple factors, only one of which is whether it was double-clicked. Second, I'll be distributing this script to others on my team and I can't realistically ask all of them to make registry changes which will affect all scripts.

Is this possible?

like image 655
Ben Blank Avatar asked Aug 23 '10 21:08

Ben Blank


People also ask

How do I pause a batch file while running?

Execution of a batch script can also be paused by pressing CTRL-S (or the Pause|Break key) on the keyboard, this also works for pausing a single command such as a long DIR /s listing. Pressing any key will resume the operation.

How do I pause a few seconds in a batch file?

TIMEOUT — Type timeout time where "time" is replaced by the number of seconds to delay. For example, typing in timeout 30 will delay your batch file for 30 seconds. If you want to prevent people from skipping the delay with a keypress, type in timeout time /nobreak (where "time" is the number of seconds to wait).

What does pause do in a batch file?

Pause examples When placed in a batch file, pause stops the file from running until you press a key to continue.

How do I stop a batch file from looping?

The only way to stop an infinitely loop in Windows Batch Script is by either pressing Ctrl + C or by closing the program.


2 Answers

Found one :-) – After desperately thinking of what cmd might do when run interactively but not when launching a batch file directly ... I finally found one.

The pseudo-variable %cmdcmdline% contains the command line that was used to launch cmd. In case cmd was started normally this contains something akin to the following:

"C:\Windows\System32\cmd.exe" 

However, when launching a batch file it looks like this:

cmd /c ""C:\Users\Me\test.cmd" " 

Small demo:

@echo off for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1 if defined DOUBLECLICKED pause 

This way of checking might not be the most robust, though, but /c should only be present as an argument if a batch file was launched directly.

Works on my machine

Tested here on Windows 7 x64. It may or may not work, break, do something weird, eat children (might be a good thing) or bite you in the nose.

like image 61
Joey Avatar answered Sep 21 '22 04:09

Joey


A consolidated answer, derived from much of the information found on this page (and some other stack overflow pages with similar questions). This one does not rely on detecting /c, but actually checks for the name of the script in the command line. As a result this solution will not pause if you double-clicked on another batch and then called this one; you had to double-click on this particular batch file.

:pauseIfDoubleClicked setlocal enabledelayedexpansion set testl=%cmdcmdline:"=% set testr=!testl:%~nx0=! if not "%testl%" == "%testr%" pause 
  1. The variable "testl" gets the full line of the cmd processor call, stripping out all of the pesky double quotes.
  2. The variable "testr" takes "testl" and further strips outs the name of the current batch file name if present (which it will be if the batch file was invoked with a double-click).
  3. The if statement sees if "testl" and "testr" are different. If yes, batch was double-clicked, so pause; if no, batch was typed in on command line (or called from another batch file), go on.

Edit: The same can be done in a single line:

echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1 

In plain English, this

  • pipes the value of %cmdcmdline% to findstr, which then searches for the current script name
  • %0 contains the current script name, of course only if shift has not been called beforehand
  • %~nx0 extracts file name and extension from %0
  • >NUL 2>&1 mutes findstr by redirecting any output to NUL
  • findstr sets a non-zero errorlevel if it can't find the substring in question
  • && only executes if the preceding command returned without error
  • as a consequence, standalone will not be defined if the script was started from the command line

Later in the script we can do:

if defined standalone pause 
like image 33
DocOc Avatar answered Sep 24 '22 04:09

DocOc