如何防止执行后关闭命令提示符?


54

我的问题是在Windows中,有些命令行窗口在执行后立即关闭。为了解决这个问题,我希望默认行为是窗口保持打开状态。通常,可以通过以下三种方法避免这种行为:

  1. pause在批处理程序后放置一行以提示用户在退出之前按一个键
  2. net start xycmd.exe(开始-运行-cmd.exe)中运行这些批处理文件或其他命令行操作工具(甚至使用类似命令或类似方法启动服务,重新启动等)
  3. cmd /k像这样运行这些程序: cmd /k myprogram.bat

但是在某些其他情况下,用户:

  1. 第一次运行该程序,并且不知道给定程序将在命令提示符(Windows命令处理器)中运行,例如从“开始”菜单(或从其他位置)运行快捷方式时,或者
  2. 觉得一直运行cmd.exe有点不舒服,并且没有时间/机会在所有地方重写这些命令的代码以在它们之后暂停或避免明确退出。

我读过一篇文章,内容涉及cmd.exe在显式打开它时更改默认行为的方法,即创建一个AutoRun条目并在以下位置操纵其内容:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor\AutoRun

(自动运行项为_String values_...)

cmd /d /k尝试了一下它的值,但这完全没有改变上面提到的东西的行为……它只是在显式打开它时改变了命令行窗口的行为(Start-Run- cmd.exe)。

那么它是怎样工作的?您能给我一些解决这个问题的想法吗?


10
您的问题以及所有的解释使我的头想爆炸。您能否说出这样的话:我想使用此“示例”命令运行批处理文件,并且希望该命令框在完成后保持打开状态。那是你的要求吗?请仔细填写代码示例。
KCotreau

1
+1同意。稍微详细一点,请重新考虑您的问题,并在可能的情况下,使用示例并提出更简洁的问题。
slotishtype

2
这是正常的行为,尽管您的问题肯定是正确的,但您应该质疑为什么以后需要保持打开命令提示符(创建大多数实用程序时要牢记这一警告)。
突破

1
我认为这不是一个真正的问题。正如您刚刚指示用户使用批处理文件一样。如果这不是问题的意图,请通过删除任何令人困惑的信息来澄清您的问题,并说明您的真正目标是什么。如果不清楚,很难给出正确的答案……
Tamara Wijsman

1
@Randolf Richardson,这是因为最终用户永远不会看到这些工具(毕竟,这就是我们现在使用GUI的原因)。如果确实需要此类信息,则大多数IT小组都会发出批处理文件,以收集相应的系统信息并进行显示。我看不到任何可能的方式是,如果在这个问题上找到解决办法,这将导致更少的问题,那么就解决了-这么多的东西被发送到stdout一个恒定的基础这是从来没有打算成为一个很好的理由可见。
突破

Answers:


27

我有一个只能应用于.cmd.bat文件的解决方案:

打开regedit并转到以下任一位置:

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
[HKEY_CLASSES_ROOT\cmdfile\shell\open\command] 

现在将“默认键值”更改为cmd.exe /k "%1" %*。现在,每个批处理脚本窗口在执行后将保持打开状态。

请注意,这类似于using cmd.exe /c cmd.exe /k program.bat,这意味着将在父实例中启动另一个CMD实例。我找不到如何覆盖第一个/c参数的方法。

您也可以使用来执行此操作[exefile],但是现在,如果可执行文件具有GUI,它将显示一个空的控制台框。


4
+1是这里唯一可实际回答给定问题的解决方案。不幸的是,我认为这可能是等待发生的内存泄漏。当服务启动新的批处理文件而不在CMD行中指定CMD.EXE时会发生什么?在这种情况下不使用此代码吗?这不是要在非交互式桌面上创建一个新窗口并将其保持打开状态直到您重新启动吗?
krowe2 2014年

@APerson您的编辑通过不包括来破坏命令*。编辑时请多加注意!
not2qubit

@ not2qubit抱歉,没有注意到我删除了三个星号,而不是两个。会做。
APerson

17

引用微软

当控制台上附加的最后一个进程终止或调用FreeConsole时,它将关闭。

换句话说,当Win32控制台窗口中运行的最后一个程序退出时,它将始终关闭,并且您无法更改它。


(对于16位MS-DOS程序,Windows在属性对话框中提供了“退出时关闭”选项,但这不是以上行为的例外:NTVDM进程将窗口保持打开状态。此外,此选项是再次按程序)。


13
+1以了解如何以及为何关闭控制台窗口(与大多数人只说“ OMG为什么无法保持打开!!!!!!!! 1111one”)相反。它的行为符合设计,应保持这种方式恕我直言。这就是为什么我们首先拥有标准流和批处理文件的主要原因。
突破

27
@Breakthrough问题How can I do X不是In your opinion, should I do X。这个答案无济于事,这意味着当局部解已经在其他地方出现时,X是不可能的。(-1)
极好的2014年

7

只需在批处理文件的位置打开命令提示符,然后手动键入批处理文件的名称即可在该窗口中运行它。

1.导航到可执行文件所在的文件夹
2.右击并选择“命令窗口从这里”
3.键入可执行文件的名称,然后按Enter键。4
.该过程应运行,但该窗口应保持打开状态


1
我不知道Shift +右键。另外,您也可以将exe拖放到cmd窗口中,该窗口会自动为您放置路径。
极好的2014年

1
这通常对我有用,但是显然不是很确定,因为我在这里寻找解决方案的原因恰恰是它在当前情况下不起作用。
RenniePet

这是最简单的解决方案,必须将其标记为正确答案
Vicky Kapadia

4

cmd.exe /k会给您带来麻烦。如果批次exit 1(不带/B),您的控制台将关闭。一个技巧是使用:

cmd.exe /k cmd /c ...

要默认将其用于所有批处理文件,请将HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default)和设置HKEY_CLASSES_ROOT\batfile\shell\open\command\(default)"%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*


1
我以为可以"%*"通过完整的参数列表,所以这不会两次通过第一个参数,一次"%1"又一次通过"%*"吗?
凯文·费根

1
@KevinFegan我没有检查原因,但是%1应该保留引号,这意味着在某些情况下它可能会被双引号引起来。还有之间的差异%1 %2 %3 ..%*我不记得了,但现在的%1 %2 %3在某些情况下,工作%*失败。
2013年

3

阅读grawity答案后,我只是想出一个愚蠢的解决方案。

我的用例是在工作中建立一个控制台环境,其中所有更合理的解决方案均被阻止。我所需要做的只是设置PATH并配置一些doskey别名,然后将其转储到Shell中。

我的解决方案(刚刚在Win7上测试)作为cmd批处理文件的最后一行添加。这将运行一个嵌套的命令提示符,该命令提示符将继承其父级的环境。该子外壳将使批处理进程保持打开状态,直到您退出,此时批处理没有子进程,并且也将退出。


2

您可以在此处使用以下解决方案,而不是使用PAUSE(在需要时,我更喜欢选择CHOICE或TIMEOUT而不是使用PAUSE):886848 / how-to-make-windows-batch-file-pause-when-双击

这样,如果您在Windows资源管理器中单击批处理文件或链接(快捷方式),则可以使批处理文件程序在退出之前暂停,以便查看程序输出和任何错误消息。

使用CHOICE,您可以对用户进行编程以选择各种动作的能力,而使用TIMEOUT可以使窗口在经过一段时间(无人照管)后关闭。如果从命令提示符窗口中运行批处理文件,这些暂停可能会很烦人。

链接的解决方案使您可以决定是否从命令提示符窗口运行了批处理文件,是否要跳过暂停。

您可以在提供的链接上阅读更多内容,但其基础是它使用环境变量:

%cmdcmdline%

确定是否从命令窗口运行了批处理文件。

因此,您可以像这样使用它:

在批处理文件将要退出的位置,您添加了如下代码:

echo %cmdcmdline:"=-% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% NEQ 0 goto :EOF
pause
goto :EOF

rem if %errorlevel% EQU 0 batch-file: %~dpf0 was executed from Windows Explorer, ...
rem if %errorlevel% NEQ 0 batch-file: %~dpf0 was executed from within a Command Prompt

1

我发现最好的解决方法是使用start从另一个批处理文件调用您的批处理文件。

因此,如果您通常运行名为go.bat的文件,则将创建另一个名为go2.bat之类的批处理文件

go2.bat的内容就是

start go.bat

第一个窗口立即关闭,但运行go.bat的窗口保持打开状态


这行得通,我只是将命令提示符可执行文件的名称放在一个bat文件(1.bat)中,该文件使用第二个bat文件“ start 1.bat”中的start命令调用。命令窗口保持打开状态。
–jectamenta

1

这适用于Windows注册表编辑器5.00版。

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

将以上cmds保存在一个名为like的文件中cmdbatfile-open.reg并执行它!


2
欢迎使用Stack Exchange!我已经为您修复了答案中的格式。请参阅此处以获取格式化帮助。另外,在发布代码时,请记住要解释其确切功能。您可能还需要阅读“ 接听方法”
Blacklight Shining

1

假设您有两个要在其各自实例中启动的批处理文件,并且在其可执行文件退出时保持打开状态。让我们将这两个批次称为A.batB.bat

现在为简单起见,您可以有一个批处理文件来同时启动它们,让我们launch_both.bat用内容来调用它:

start cmd /k "A.bat & cmd /c"
start cmd /k "B.bat & cmd /c"

如果您调用exit两个批处理文件之一,它可能无法按预期方式工作。那将需要测试。


0

对于使用Windows 10的用户,请注意,以上所有答案当前均不适用于Windows 10。

对于Windows 10,如果有权访问该脚本,则需要在末尾添加以下代码:

read

该代码将在关闭之前等待输入。


请记住,这个问题是在Windows 10(5年前)之前问的,请用更多信息编辑您的答案
yass

0

针对降级的PSIXO,“问题中已经涵盖了此答案。– Ro Yo Mi 16年1月20日,下午5:06” –不,不是。先前的答案是:“暂停”,它不起作用。PSIXO的答案是:“&暂停”,它确实起作用。在降级之前,请更仔细地分析。我从一个IDLE提示符处运行了它,它起作用了:

    >>> os.system('dir ^ & pause')
    0
    >>> 

另一方面:

    >>> os.system('dir ^ pause')
    1
    >>>

无效(cmd提示被跳过,实际上返回了错误(1))。感谢PSIXO提供我所需的答案。亨利

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.