双击时如何使Windows批处理文件暂停?

时间:2009-05-20 08:36:52

标签: windows batch-file

我编写了一个批处理文件来自动执行某些任务。我可以从命令窗口运行它,它运行并显示结果。如果我从资源管理器中双击它,它会立即运行并终止,所以我看不到结果。

有没有办法可以让批处理文件窗口保持打开状态,直到我通过双击图标启动它来解除它?

当我从命令行调用批处理文件时,我不想传递/ nopause参数。我想要一个解决方案,我可以使用批处理文件,而不必做任何太特别的事情?

感谢。

注意我不希望它从命令行运行时暂停!!我可以从另一个批处理文件中调用此批处理文件来执行一系列操作。在那种情况下,我不能坐在那里继续打击。

理想情况下,最好是我可以在批处理文件中放入一些代码,以便它可以解决它从哪里开始,然后暂停或不适当。

7 个答案:

答案 0 :(得分:14)

使用:

cmd /K myBatch.bat

作为您的捷径。

答案 1 :(得分:4)

这是一个应该运行良好的解决方案,并考虑批处理文件可能调用另一个批处理文件(“嵌套”)的可能性。

如果从“命令提示符”运行批处理文件,您可以使用“查找”查找“/ c”,该文件不应存在:

echo %cmdcmdline% | find /i "/c"

但是,您可以通过使用“查找”搜索更长的字符串或批处理文件名来进行更“强大”的测试。

如果搜索字符串中包含(“)双引号,”查找“命令将无法正常工作。要解决此问题,您可以使用环境变量替换来”调整“字符串,以便它与查找:

set newcmdcmdline=%cmdcmdline:"=-%

这通常会返回:

if the batch-file is run from a "Command Prompt"  
    newcmdcmdline=-C:\Windows\system32\cmd.exe-

if the batch-file is run by clicking on the the batch-file  
(or the batch-file shortcut) from "Windows Explorer"  
    newcmdcmdline=cmd /c --D:\Path\test.cmd- -

然后您可以使用“查找”来测试:

    echo %newcmdcmdline% | find /i "cmd /c --"
or
    echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"

接下来,您需要确定是否希望“嵌套”批处理文件的行为就像您以与调用批处理文件相同的方式执行它,或者您希望嵌套批处理文件始终表现得好像它们是从“命令提示符”执行的。

考虑一下,如果您在嵌套的批处理文件中运行,那么测试一下:

echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"

将始终失败(不匹配),因为%newcmdcmdline%包含最外面的批处理文件的名称,而不是嵌套的批处理文件。

因此第一个解决方案对于调用批处理文件和所有嵌套批处理文件的行为都相同。如果您不调用任何批处理文件,也是完美的:

在您要进行此测试的所有批处理文件(调用和嵌套)中,添加这些行,通常位于批处理文件的顶部附近(如果您愿意,可以排除echo语句):

if not defined withincmd call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from within a Command Prompt
rem if %withincmd% EQU 0 pause

然后,在每个批处理文件中的某处,添加testshell子函数:

goto :EOF
:testshell
rem "Nested" batch-files won't see this because withincmd is already defined
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF

您只能在最外面的批处理文件的顶部对“testshell”进行一次条件调用。

在某些情况下,如果从“命令提示符”执行,则可能只希望“最外层”批处理文件的行为不同,而不是通过单击批处理文件(或批处理文件)来运行它。文件快捷方式)来自“Windows资源管理器”。因此,无论它们如何运行,从“最外层”批处理文件调用的批处理文件的行为总是相同。

为了实现这一点,你有几个选择。

1)在调用另一个批处理文件之前保存“withincmd”的值,并在调用的批处理文件返回后恢复之前的“withincmd”值。在大多数情况下,这有点牵扯。

2)在每个批处理文件中为“withincmd”使用“全局唯一”变量名称。

3)每次您需要知道当前批处理文件的运行方式时,执行“查找”命令。

4)在进入批处理文件时递增变量并在批处理文件退出时递减它,然后仅测试批处理文件的运行方式如果count-variable = 1

方法3是最简单的方法,但有一个缺点,即如果从自身(如在递归中)或另一个批处理文件中调用最外面的批处理文件,则不会正确设置测试变量(withincmd)。

以下是使用方法3的方法:

在您要进行此测试的所有批处理文件(调用和嵌套)中,添加这些行,通常位于批处理文件的顶部附近(如果您愿意,可以排除echo语句):

call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from (or Nested) within a Command Prompt
rem if %withincmd% EQU 0 pause

然后,在每个批处理文件中的某处,添加testshell子函数:

goto :EOF
:testshell
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF

在这种情况下,您必须在EACH批处理文件的顶部调用“testshell”一次,然后在调用另一个批处理文件(或每次需要知道时调用“testshell”)后再调用一次当前批处理文件的运行方式。)

以下是使用方法4的方法:

在您要进行此测试的所有批处理文件(调用和嵌套)中,添加这些行,通常位于批处理文件的顶部附近(如果您愿意,可以排除echo语句):

if not defined nestinglevel set nestinglevel=0
set /A nestinglevel=nestinglevel+1
call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from (or Nested) within a Command Prompt
rem if %withincmd% EQU 0 pause

然后,在每个批处理文件中的某处,添加testshell子函数:

goto :EOF
:testshell
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
if %nestinglevel% GEQ 2 goto :EOF
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF

另外,请记住在退出一个批处理文件时递减变量以返回到调用批处理文件:

set /A nestinglevel=nestinglevel-1

在这种情况下,您必须在EACH批处理文件的顶部调用“testshell”一次,然后在调用另一个批处理文件(或每次需要知道时调用“testshell”)后再调用一次当前批处理文件的运行方式。)

在所有情况下,测试%withincmd%以确定当前批处理文件的运行方式,如下所示:

if %withincmd% EQU 0 pause
if %withincmd% EQU 1 goto :EOF

答案 2 :(得分:3)

在文件打印结束时

pause

它将等待任何键输入

答案 3 :(得分:1)

我的问题很相似 - 如果从Windows资源管理器调用,我想在最后停顿,但如果在命令窗口中没有暂停。我想出了这个。 在每个批处理文件的顶部,输入:

if "%parent%"=="" set parent=%~0
if "%console_mode%"=="" (set console_mode=1& for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set console_mode=0)

然后在结束

if "%parent%"=="%~0" ( if "%console_mode%"=="0" pause )

它处理嵌套批量调用,您只想在原始批处理文件的末尾暂停,而不是在嵌套批处理文件中暂停。在嵌套批处理文件中,%parent%已设置为原始调用方,因此它不等于嵌套的%~0。如果您bat1调用bat2,则会在资源管理器中打开双击bat2的选项 - 在该上下文中bat2将在结束时暂停,而如果bat1调用{ {1}},然后bat2不会在结尾处暂停(只有bat2会暂停)。

bat1语句分隔符有助于避免对主函数次要的东西造成视觉混乱。如果您不喜欢它的外观,只需将每个语句放在一个新行上即可。

此方法将&视为启动命令(/C)中的一个参数。它假定您的批处理文件不使用%cmdcmdline%选项。如果您自己使用/C,则需要检查/C中是否显示%COMSPEC%(使用%cmdcmdline%)。当资源管理器启动bat文件时,其FINDSTR包括%cmdcmdline%,例如%COMSPEC%。在命令窗口中,C:\Windows\System32\cmd.exe /C double_clicked_batch_file_name中只有%cmdcmdline%(无路径)。我使用的是cmd.exe而不是CALL mybat,但您可能需要使用现有的批处理文件。

答案 4 :(得分:0)

您只需将params添加到批处理调用中,并在批处理中处理有条件的暂停语句。因此,当从命令行或dblclick启动时,批处理可以暂停,当从其他批处理调用时,/ nopause param不会暂停。

答案 5 :(得分:-1)

在批处理文件中使用“暂停”,它将等待用户输入

HTH

答案 6 :(得分:-1)

暂停命令会起作用吗?

Microsoft Documentation on pause