11

コンソールUIを介してユーザーと対話するJavaアプリケーションを呼び出すDOSバッチスクリプトがあります。議論のために、それを呼びましょう、runapp.batそしてその内容は

java com.example.myApp

バッチスクリプトがコンソールで呼び出される場合、すべてが正常に機能します。ただし、スクリプトがウィンドウマネージャーから呼び出された場合、新しく開いたコンソールは、アプリケーションの実行が終了するとすぐに閉じます。私が欲しいのは、すべての場合にコンソールを開いたままにしておくことです。

私は次のトリックを知っています:

  • pauseスクリプトの最後にコマンドを追加します。runapp.batコマンドラインから呼び出された場合、これは少し醜いです。

  • これを使用して新しいシェルを作成するcmd /K java com.example.myAppこれは私がこれまでに見つけた最良の解決策ですが、コマンドラインから呼び出されたときに余分なシェル環境が残るため、呼び出しexitても実際にはシェルが閉じられません。

もっと良い方法はありますか?

4

6 に答える 6

12

この質問を参照してください:バッチ ファイルの実行方法の検出

このスクリプトは、コマンド コンソールから実行すると一時停止しませんが、エクスプローラーでダブルクリックすると一時停止します。

@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
于 2009-02-04T12:02:44.100 に答える
3
cmd /K java com.example.myApp & pause & exit

仕事をします。&はコマンドを次々に実行します。&&を使用すると、失敗した場合に破損する可能性があります。

于 2009-06-10T15:59:10.977 に答える
1

次の行をバッチ ファイルに含め、エクスプローラーでバッチ ファイルをダブルクリックします。

cmd /k "&& で区切られたこれらの引用符内のスクリプト コマンド"

例えば

cmd /k "cd ../.. && dir && cd some_directory"

cmd の完全なオプションは、ここにあります。

于 2010-12-04T18:27:22.760 に答える
0

私は代替シェル (主に jpsoft.com の TCC/LE) とサブシェルを頻繁に使用します。このコードは、より広く、より一般的なケースで機能することがわかりました (そして、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_commandNULL 拡張子の変更if /i "%~$PATH:2"=="%~$PATH:3"と追加のコード チェックにより、完全修飾されていないパス (たとえば、'cmd.exe' または 'tcc' だけで呼び出されるサブシェル) で開かれたシェル/サブシェルに対してコードが機能するようになります。

拡張子のない引数の場合、このコードは解析せず、%PATHEXT% からの拡張子を使用します。基本的に、拡張子のないコマンドを検索するときに CMD.exe が使用する拡張子の階層を無視します (最初に FOO.com、次に FOO.exe、次に FOO.bat を試行します)。その_is_similar_commandため、シェル コマンドとしての 2 つの引数の同等性ではなく、類似性をチェックします。これは混乱/エラーの原因になる可能性がありますが、このアプリケーションの実際の問題として発生することはほとんどありません。

編集:最初のコードは古いバージョンでした。コードは最新バージョンに更新されました。(1) スワップ%COMSPEC%%cmdcmdline%れ、最初の呼び出しで、(2) 複数の%cmdcmdline%引数のチェックが追加されました。(3) エコーされたメッセージは、検出されたものについてより具体的です。(4) ) 新しい変数%_PAUSE_NEEDED%が追加されました。

%_FROM_CONSOLE%は、バッチ ファイルがコンソール コマンド ラインから直接実行されたか、エクスプローラまたはその他の手段を介して間接的に実行されたかに基づいて設定されることに注意してください。これらの「その他の手段」には、perl system() 呼び出し、または などのコマンドの実行が含まれcmd /c COMMANDます。

この変数%_PAUSE_NEEDED%は、バッチ ファイルを間接的に実行するプロセス (perl など) がバッチ ファイル内の一時停止をバイパスできるようにするために追加されました。これは、出力が表示されているコンソールにパイプされていない場合 (例: perl -e "$o = qx{COMMAND}") に重要です。このような場合に一時停止が発生すると、「Press any key to continue . . .」というメッセージが表示されます。一時停止プロンプトがユーザーに表示されることはなく、プロセスはユーザー入力のプロンプトが表示されないのを待ってハングします。ユーザーの操作が不可能または許可されていない場合は、%_PAUSE_NEEDED%変数を "0" または "1" (それぞれ false または true) に事前設定できます。%_FROM_CONSOLE%は引き続きコードによって正しく設定されますが、 の値%_PAUSE_NEEDED%はその後 に基づいて設定されません%_FROM_CONSOLE%。通過するだけです。

%_FROM_CONSOLE%また、サブシェルがスイッチ/オプション (例: ) を含むコマンドで開かれている場合、コードはサブシェル内での実行を間接的 ( =0) として誤って検出することにも注意してくださいcmd /x。通常、サブシェルは追加のスイッチなしで開かれ%_PAUSE_NEEDED%、必要に応じて 0 に設定できるため、これは大きな問題ではありません。

警告コード。

于 2009-05-03T04:27:34.150 に答える
-2

@エコー %CMDCMDLINE% | find /I " /c " >nul && 一時停止

于 2014-04-17T20:47:10.847 に答える