16

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
Álvaro González
  • 142,137
  • 41
  • 261
  • 360

3 Answers3

20
@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
Anders
  • 97,548
  • 12
  • 110
  • 164
  • While it's not perfect (there's another scenario, scripts ran from other scripts) it's basically what I had in mind. – Álvaro González Oct 18 '10 at 09:39
  • 1
    I'd suggest changing `find` to `%WINDIR%\system32\find.exe`, otherwise it will not work if one have Cygwin installed and added to `PATH`. – n0rd Apr 19 '11 at 11:12
  • One other comment, as far as I can tell, this trick works just fine with batch files called from other batch files. Ie, dbl click on a bat file that performs a CALL NEXTBATCH.bat, and then use this trick in either of those bat files, and you'll still get the correct indicator of CLI vs GUI. – DarinH Apr 26 '11 at 14:55
  • @DarinH I realize your comment is over 3 years old, but could you please clarify? What you describe does not work for me. NextBatch.bat contains the pause line. FirstBatch.bat calls NextBatch.bat. Double-clicking on NextBatch.bat does indeed pause, but double-clicking on FirstBatch.bat does not. – skataben Oct 03 '14 at 15:14
  • The "call Next.bat" detection should not work but since you already know you are in a batch file you can set a environment variable or just add the conditional pause line to First.bat as well... – Anders Oct 03 '14 at 18:42
  • 1
    This fails if the command line contains spaces and escaped double quotes, which happens when running from the MSBuild tools command prompt. This alternative works in that case: `ECHO.%CMDCMDLINE%|find /I "%~0" >NUL` then `IF NOT ERRORLEVEL 1 PAUSE` – EM0 Dec 10 '15 at 17:39
  • 1
    @EM Yes, that is a good point. You are always going to be fighting quotes and escapes in batch files because of the flaws in the "language". – Anders Dec 10 '15 at 18:19
3

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.

Tom Smilack
  • 2,057
  • 15
  • 20
  • 3
    If you are creating shortcuts, the shortcut command could just be >>%comspec% /k "c:\yourfile.bat"<< and it would leave the window open, or you could execute >>%comspec% /c "c:\yourfile.bat"&pause<< Also, .pif files (Old school .bat "shortcuts") have a option to close/leave the window open... – Anders Oct 14 '10 at 22:15
0

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.

Community
  • 1
  • 1
skataben
  • 2,023
  • 1
  • 22
  • 25