#1 18 May 2018 03:58

Shane
Member
From: Alberta
Registered: 17 May 2018
Posts: 5

How was batch file launched?

Greetings,

A few times I have accidentally (double)-clicked a batch file. How can I tell if a batch script hasn't been launched from the console/command line? This would be similar to launching it from the Windows Run command.

Thanks,
Shane.

Last edited by Shane (19 May 2018 07:49)


Windows 10 Home 64-bit

Offline

#2 18 May 2018 11:55

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 977
Website

Re: How was batch file launched?

The simple way would be to check for a command line parameter, if you dont already have one then use some dummy text

myscript.cmd OK

Then in the script..

@ echo off
IF "%1"=="OK" goto :start
echo started by double click
goto:eof

:start
echo rest of script

Offline

#3 18 May 2018 15:14

Pyprohly
Member
Registered: 26 Nov 2014
Posts: 37

Re: How was batch file launched?

Here’s a way to determine the execution context. Be aware though that it creates quite a bit of overhead.

@echo off

goto :main

:get_script_pid [OutVar]
setlocal
	for /f "skip=1" %%I in ('
		wmic process Where "Name='cmd.exe'" Get ParentProcessId
	') do for %%J in (%%I) do set "pid=%%J"
endlocal & if "%~1"=="" (echo(%pid%) else set "%~1=%pid%"
goto :eof

:get_parent_pid [OutVar]
setlocal
	for /f "skip=1" %%I in ('
		wmic process Where "Name='cmd.exe'" Get ParentProcessId
	') do for %%J in (%%I) do (
		for /f %%K in ('
			2^>nul wmic process Where "ProcessId='%%J'" Get ParentProcessId
		') do for %%L in (%%K) do set "ppid=%%L"
		)
	)
endlocal & if "%~1"=="" (echo(%ppid%) else set "%~1=%ppid%"
goto :eof

:get_execution_context
REM execution_context values:
REM 0 = Explorer
REM 1 = Command Prompt
REM 2 = PowerShell
setlocal
	call :get_script_pid pid
	call :get_parent_pid ppid

	2>&1 wmic process Where "(ProcessId='%pid%' And (CommandLine Like '%%%~nx0%%'))" | >nul findstr -c:"No Instance(s) Available." && (
		2>&1 wmic process Where "(ProcessId='%pid%' And Name='cmd.exe')" | >nul findstr -c:"No Instance(s) Available." && (
			set /a execution_context=0
		) || (
			set /a execution_context=1
		)
	) || (
		2>&1 wmic process Where "(ProcessId='%ppid%' And Name='powershell.exe')" | >nul findstr -c:"No Instance(s) Available." && (
			set /a execution_context=0
		) || (
			set /a execution_context=2
		)
	)
endlocal & set /a execution_context=%execution_context%
goto :eof

:main

call :get_execution_context

if %execution_context% equ 0 (
	echo Batch file invoked from Explorer
	pause
) else if %execution_context% geq 1  (
	echo Batch script called from the command line
)

Offline

#4 18 May 2018 23:15

Aacini
Member
Registered: 05 Dec 2012
Posts: 138

Re: How was batch file launched?

You may use the predefined CMDCMDLINE variable:

@echo off
if /I "%CMDCMDLINE:~1,5%" equ "md /c" (
   echo Started via double-click from explorer
) else (
   echo Started from command-line
)
pause

Antonio

Offline

#5 19 May 2018 09:40

Shane
Member
From: Alberta
Registered: 17 May 2018
Posts: 5

Re: How was batch file launched?

Thanks for the suggestions.

It looks like this is the best way:

echo %CmdCmdLine%

The output will vary depending if it was launched by File Explorer or the command prompt. For example, this is what it looks like from the console/command line:

C:\WINDOWS\system32\cmd.exe

And from File Explorer or Run it looks like this:

C:\WINDOWS\system32\cmd.exe /c ""C:\Users\Shane\Documents\restore\batch_files\whoCalled.cmd

So I search the string for command argument (" /c "), and if found, exit. This is what I've created:

echo %CmdCmdLine% | findstr /c:" /c " >nul && exit /b

This line has three parts. The second part checks %CmdCmdLine% for a string (" /c "). Part three exits the batch file if the string was found in part two.

If someone (mainly me) were to accidentally click on a batch file again, the console window will flash, but then the batch file quickly exits.

Thanks again for everyone's help.
Shane.


Windows 10 Home 64-bit

Offline

#6 22 May 2018 22:23

bluesxman
Member
From: UK
Registered: 29 Dec 2006
Posts: 1,052

Re: How was batch file launched?

In the same ballpark, though not sure if this precise trick still works:

if /i "%cmdcmdline:"=%" EQU "%comspec% " (echo:started from cmd window) else (echo:started from a link/explorer)

Ref https://ss64.org/viewtopic.php?id=931

Last edited by bluesxman (22 May 2018 22:26)


cmd | *sh | Ruby | Chef | Puppet | PowerShell | AutoIT3

Offline

#7 23 May 2018 10:15

Shane
Member
From: Alberta
Registered: 17 May 2018
Posts: 5

Re: How was batch file launched?

What does "%cmdcmdline:"=%" evaluate to? Is this 'string substitution'?

I thought maybe it was a string literal, but there are an odd number of quotes.

Thanks,
Shane.

Last edited by Shane (23 May 2018 10:19)


Windows 10 Home 64-bit

Offline

#8 25 May 2018 23:12

bluesxman
Member
From: UK
Registered: 29 Dec 2006
Posts: 1,052

Re: How was batch file launched?

Yes, it's string substitution -- it's removing any quotes from the variable.  The reason being than when you launch from a link/explorer %cmdcmdline% comes out like this:

C:\Windows\system32\cmd.exe /c ""D:\Users\somename\x.cmd" "

And the extra quotes combine with technical limitations in cmd.exe to break the comparison to %comspec%.

This trick works because, when running a script from cmd.exe %cmdcmdline% comes out like so:

C:\Windows\system32\cmd.exe<SPACE>

Where <SPACE> is a literal space character.

Last edited by bluesxman (25 May 2018 23:13)


cmd | *sh | Ruby | Chef | Puppet | PowerShell | AutoIT3

Offline

Board footer

Powered by FluxBB