You are not logged in.
Pages: 1
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
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
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
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
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
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
Offline
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
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
Offline
Pages: 1