代码之家  ›  专栏  ›  技术社区  ›  ykaganovich Mike Samuel

在批处理脚本中,是否有方法仅在从Windows管理器调用时保持控制台打开?

  •  11
  • ykaganovich Mike Samuel  · 技术社区  · 17 年前

    我有一个DOS批处理脚本,它调用java应用程序,该应用程序通过控制台UI与用户交互。为了便于讨论,让我们把它称为 runapp.bat

    java com.example.myApp
    

    如果在控制台中调用批处理脚本,则一切正常。但是,如果从窗口管理器调用脚本,则新打开的控制台将在应用程序完成执行后立即关闭。我想要的是控制台在任何情况下都保持打开状态。

    我知道以下窍门:

    • pause 脚本末尾的命令。以防万一,这有点难看 runapp.bat 从命令行调用。

    • cmd /K java com.example.myApp 这是迄今为止我找到的最好的解决方案,但是从命令行调用时会留下一个额外的shell环境,因此调用 exit

    有更好的办法吗?

    6 回复  |  直到 17 年前
        1
  •  12
  •   Community Mohan Dere    9 年前

    Detecting how a batch file was executed

    如果从命令控制台运行此脚本,则不会暂停,但如果在资源管理器中双击,则会暂停:

    @echo off
    setlocal enableextensions
    
    set SCRIPT=%0
    set DQUOTE="
    
    :: Detect how script was launched
    @echo %SCRIPT:~0,1% | findstr /l %DQUOTE% > NUL
    if %ERRORLEVEL% EQU 0 set PAUSE_ON_CLOSE=1
    
    :: Run your app
    java com.example.myApp
    
    :EXIT
    if defined PAUSE_ON_CLOSE pause
    
        2
  •  3
  •   ykaganovich Mike Samuel    17 年前

    我更喜欢使用 %cmdcmdline% 正如帕特里克对另一个问题的回答的评论中所说的(虽然我看了一下,但没有发现)。这样,即使有人决定使用引号来调用批处理脚本,也不会触发误报。

    @echo off
    java com.example.myApp %1 %2
    
    REM "%SystemRoot%\system32.cmd.exe"   when from console
    REM cmd /c ""[d:\path\script.bat]" "  when from windows explorer
    
    @echo %cmdcmdline% | findstr /l "\"\"" >NUL
    if %ERRORLEVEL% EQU 0 pause
    
        3
  •  3
  •   Totonga    17 年前
    cmd /K java com.example.myApp & pause & exit
    

    我会做好的。政府;将一个接一个地执行命令。如果您使用&&如果一个失败了,你可以打破它。

        4
  •  1
  •   tjb    15 年前

    在批处理文件中包含此行,然后在资源管理器中双击批处理文件:

    cmd/k“这些引号中的脚本命令由&&分隔

    例如

    可以找到cmd选项的完整补充 here

        5
  •  0
  •   rivy    17 年前

    我经常使用备用shell(主要是来自jpsoft.com的TCC/LE)和子shell。我发现此代码适用于更广泛、更一般的情况(并且不需要FINDSTR):

    @echo off & setlocal
    if "%CMDEXTVERSION%"=="" ( echo REQUIRES command extensions & exit /b 1 ) &:: REQUIRES command extensions for %cmdcmdline% and %~$PATH:1 syntax
    
    call :_is_similar_command _FROM_CONSOLE "%COMSPEC%" %cmdcmdline%
    if "%_PAUSE_NEEDED%"=="0" ( goto :_START )
    if "%_PAUSE_NEEDED%"=="1" ( goto :_START )
    set _PAUSE_NEEDED=0
    if %_FROM_CONSOLE% equ 0 ( set _PAUSE_NEEDED=1 )
    goto :_START
    ::
    :_is_similar_command VARNAME FILENAME1 FILENAME2
    :: NOTE: not _is_SAME_command; that would entail parsing PATHEXT and concatenating each EXT for any argument with a NULL extension
    setlocal
    set _RETVAL=0
    :: more than 3 ARGS implies %cmdcmdline% has multiple parts (therefore, NOT direct console execution)
    if NOT [%4]==[] ( goto :_is_similar_command_RETURN )
    :: deal with NULL extensions (if both NULL, leave alone; otherwise, use the non-NULL extension for both)
    set _EXT_2=%~x2
    set _EXT_3=%~x3
    if NOT "%_EXT_2%"=="%_EXT_3%" if "%_EXT_2%"=="" (
        call :_is_similar_command _RETVAL "%~2%_EXT_3%" "%~3"
        goto :_is_similar_command_RETURN
        )
    if NOT "%_EXT_2%"=="%_EXT_3%" if "%_EXT_3%"=="" (
        call :_is_similar_command _RETVAL "%~2" "%~3%_EXT_2%"
        goto :_is_similar_command_RETURN
        )
    ::if /i "%~f2"=="%~f3" ( set _RETVAL=1 )  &:: FAILS for shells executed with non-fully qualified paths (eg, subshells called with 'cmd.exe' or 'tcc')
    if /i "%~$PATH:2"=="%~$PATH:3" ( set _RETVAL=1 )
    :_is_similar_command_RETURN
    endlocal & set "%~1=%_RETVAL%"
    goto :EOF
    ::
    
    :_START
    
    if %_FROM_CONSOLE% EQU 1 (
        echo EXEC directly from command line
      ) else (
        echo EXEC indirectly [from explorer, dopus, perl system call, cmd /c COMMAND, subshell with switches/ARGS, ...]
        )
    if %_PAUSE_NEEDED% EQU 1 ( pause )
    

    if /i "%~f2"=="%~f3" _is_similar_command 子程序。改为 if /i "%~$PATH:2"=="%~$PATH:3" 另外,检查空扩展名的代码允许代码用于使用非完全限定路径打开的shell/subshell(例如,仅使用“cmd.exe”或“tcc”调用的subshell)。

    对于没有扩展名的参数,此代码不分析并使用来自%PATHEXT%的扩展名。它实际上忽略了CMD.exe在搜索没有扩展名的命令时使用的扩展名层次结构(首先尝试FOO.com,然后是FOO.exe,然后是FOO.bat,等等)。所以 __与_命令类似吗 作为shell命令检查两个参数之间的相似性,而不是等效性。这可能会导致混淆/错误,但很可能在实际应用中不会出现问题。

    编辑: 最初的代码是旧版本。代码现在更新为最新版本,该版本具有:(1)交换 %COMSPEC% %cmdcmdline% 在初始调用中,(2)添加了对多个 参数,(3)回显消息更具体地说明检测到的内容,(4)新变量 %_PAUSE_NEEDED%

    应当指出的是 %_FROM_CONSOLE% 是根据批处理文件是直接从控制台命令行还是通过资源管理器或其他方式间接执行而设置的。这些“其他方法”可以包括一个perl system()调用或通过执行以下命令 cmd /c COMMAND

    变量 %_需要暂停% 添加,以便间接执行批处理文件的进程(如perl)可以绕过批处理文件中的暂停。这在输出未通过管道传输到可见控制台的情况下非常重要(例如, perl -e "$o = qx{COMMAND}" 变量可以预设为“0”或“1”(分别为假或真)。 %_从控制台% %_需要暂停% 之后不会根据 %_从控制台% . 它刚刚通过。

    还要注意,代码会错误地将执行检测为间接执行( cmd /x %_需要暂停% 如有必要,可将设置为0。

    警告密码。

        6
  •  -2
  •   Dave Brown    12 年前

    @echo%cmdline%| find/I”/c“>nul&&暂停

    推荐文章