Detect if bat file is running via double click or from cmd window

前端 未结 12 1535
醉话见心
醉话见心 2020-12-29 02:54

I have a bat file that does a bunch of things and closes the cmd window which is fine when user double clicks the bat file from explorer. But if I run the bat file from a al

相关标签:
12条回答
  • 2020-12-29 03:19

    @dlchambers was close but set didn't work since cmdcmdline isn't a defined environment variable in some cases, but this version based on his works great for me:

    echo %cmdcmdline% | findstr /i pushd >nul
    if errorlevel 1 pause
    
    0 讨论(0)
  • 2020-12-29 03:32

    Use exit /b 0, not exit

    The former will exit all the way if launched from Windows Explorer, but return to the console if launched from the command line.

    0 讨论(0)
  • 2020-12-29 03:32

    It's not only possible, but your desired behavior is the normal behavior of batch file execution, unless you do something 'special':

    • when executing a batch file by double-clicking it in Explorer, the cmd window will close when it's done;
    • when the batch file is executed from the command line, it simply returns to the command line prompt when complete - the window is not closed;

    So I think the question that needs to be answered is what are you doing in the batch file that causes the command window to close when you execute it by the command line?

    0 讨论(0)
  • 2020-12-29 03:36

    Paste this at the beginning of your BAT or CMD script and maybe change what happens in the 'if' clause:

    :: To leave command window open if script run from Windows explorer.
    @setlocal
    @set x=%cmdcmdline:"=%
    @set x=%x: =%
    @set y=%x:cmd/c=%
    @if "%x%" neq "%y%" cmd /k %0 %* && exit || exit
    @endlocal
    

    What this does, is if the user either double-clicks or calls this script using "cmd /c" it will re-launch with "cmd /k" which will leave the session open after the command finishes. This allows the user to EXIT or maybe do something else.

    The reason for doing it this way rather than the other ways explained in this answer is because I've found situations that still even with using the quotes or other symbols, the IF statement would barf with certain situations of the QUOTES and the /c and with spaces. So the logic first removes all QUOTES and then removes all spaces.. because SOMETIMES there is an extra space after removing the quotes.

    set x=%cmdcmdline:"=%       <-- removes all quotes
    set x=%x: =%                <-- removes all spaces
    set y=%x:cmd/c=%            <-- removes  cmd/c  from the string saving it to  y
    

    The point of the && exit || exit is so that if the ERRORLEVEL before exiting is 0 (success) it then stops running, but also if it is non 0 (some failure) it also stops running.

    But you can replace this part:

    cmd /k %0 %* && exit || exit
    

    with something like

    set CALLED_WITH_CMD_C=YES
    

    and then make up your own differences in the rest of your script. You would have to then move or remove the endlocal.

    The '@' symbol at front just prevents the echo, which you can have if you want to test. Do not use echo on or echo off as it changes the setting and affects all subsequent scripts that call yours.

    0 讨论(0)
  • 2020-12-29 03:37

    %cmdcmdline% gives the exact command line used to start the current Cmd.exe.

    • When launched from a command console, this var is "%SystemRoot%\system32\cmd.exe".
    • When launched from explorer this var is cmd /c ""{full_path_to_the_bat_file}" ";
      this implicates that you might also check the %0 variable in your bat file, for in this case it is always the full path to the bat file, and always enclosed in double quotes.

    Personally, I would go for the %cmdcmdline% approach (not %O), but be aware that both start commands can be overridden in the registry…

    0 讨论(0)
  • 2020-12-29 03:37

    after reading through the suggestions, this is what I went with:

    set __cmdcmdline=%cmdcmdline%
    set __cmdcmdline=%__cmdcmdline:"=%
    set __cmdcmdline=%__cmdcmdline: =%
    set __cmdcmdline=%__cmdcmdline:~0,5%
    if "%__cmdcmdline%"=="cmd/c" set CMD_INITIATED_FROM_EXPLORER=1
    set __cmdcmdline=
    

    which conditionally sets the variable: CMD_INITIATED_FROM_EXPLORER

    ..and can subsequently be used as needed:

    if defined CMD_INITIATED_FROM_EXPLORER (
      echo.
      pause
    )
    

    ..but the issue regarding Powershell that @Ruben Bartelink mentions isn't solved:

    running ./batch.cmd from Powershell uses cmd /c under the hood

    0 讨论(0)
提交回复
热议问题