2011-07-04 15:32:05 +0000 2011-07-04 15:32:05 +0000
56
56

Como evitar que o prompt de comando feche após a execução?

O meu problema é que no Windows, existem janelas de linha de comando que fecham imediatamente após a execução. Para resolver isto, eu quero que o comportamento padrão seja que a janela seja mantida aberta. Normalmente, este comportamento pode ser evitado com três métodos que me vêm à cabeça:

  1. Colocar uma linha pause após os programas em lote para solicitar ao utilizador que pressione uma tecla antes de sair do
  2. Executar estes ficheiros batch ou outras ferramentas de manipulação de linha de comando (mesmo arranque do serviço, reinício, etc. com net start xy ou algo semelhante) dentro do cmd.exe(Start - Run - cmd.exe)
  3. Correr estes programas com cmd /k assim: cmd /k myprogram.bat

Mas existem alguns outros casos em que o utilizador:

  1. Executa o programa na primeira vez e não sabe que o programa em questão será executado no Command Prompt (Windows Command Processor), por exemplo, ao executar um atalho do menu Iniciar (ou de outro lugar), OR
  2. Considera um pouco desconfortável rodar cmd.exe o tempo todo e não tem tempo/oportunidade para reescrever o código destes comandos em qualquer lugar para colocar uma pausa depois deles ou evitar sair explicitamente.

Eu li um artigo sobre a mudança do comportamento padrão do cmd.exe ao abri-lo explicitamente, com a criação de um AutoRun entry e manipulando o seu conteúdo nestes locais:

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

(Os itens AutoRun são _String values_…)

Eu coloquei o cmd /d /k como um valor para tentar, mas isto não alterou em nada o comportamento dos itens acima mencionados… Apenas alterou o comportamento da janela da linha de comando ao abri-la explicitamente (Start-Run-cmd.exe).

Então, como funciona? Pode dar-me alguma ideia para resolver este problema?

Respostas (11)

18
18
18
2011-07-04 17:45:20 +0000

Citação Microsoft :

Uma consola é fechada quando o último processo ligado a ela termina ou chama a FreeConsole.

Em outras palavras, a janela da consola Win32 será sempre fechada quando o último programa em execução dentro dela sair, e você não pode alterar isso.


(Para programas MS-DOS de 16 bits, o Windows oferece uma opção “Fechar na saída” no diálogo de propriedades, mas isto não é uma excepção ao comportamento acima descrito: é o processo NTVDM que mantém a janela aberta. Além disso, esta opção é novamente por programa).

8
8
8
2013-03-21 14:10:13 +0000

Basta abrir um prompt de comando na localização do seu ficheiro de lote e digitar manualmente o nome do seu ficheiro de lote para o executar dentro dessa janela.

1.Navigate to the folder where your executable resides 2.Shift-Right click and select “Command Window from here” 3.type in the name of the executable and hit enter 4.The process should run, but the window should stay open

4
4
4
2012-11-06 13:37:01 +0000

cmd.exe /k vai dar-lhe problemas com algum lote. Se o lote exit 1 (sem /B) a sua consola será fechada. Um truque é usar:

cmd.exe /k cmd /c ...

Para usar isto por defeito para todos os ficheiros de lote, defina HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default) e HKEY_CLASSES_ROOT\batfile\shell\open\command\(default) para "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.

3
3
3
2014-04-26 16:55:23 +0000

Acabei de me atirar a uma solução idiota depois de ler a resposta da grawity.

O meu caso de utilização foi a criação de um ambiente de consola no trabalho onde todas as soluções mais razoáveis são bloqueadas. Tudo o que eu preciso é configurar o PATH e configurar alguns pseudónimos de dosificação e ser despejado na shell.

A minha solução (apenas testada em Win7) como adicionar cmd como a última linha no ficheiro de lote. Isto executa um prompt de comando aninhado que herda o ambiente do seu pai. Essa shell filha mantém o processo de lote aberto até que você saia, momento em que o lote não tem processos filhos e também sai.

2
2
2
2015-12-11 17:02:56 +0000

Suponha que tem dois ficheiros batch que quer lançar no seu próprio exemplo e manter abertos se as suas saídas executáveis forem executadas. Vamos chamar esses dois lotes A.bat e B.bat.

Agora para simplificar pode ter um ficheiro batch para lançar os dois, vamos chamar esse launch_both.bat com o conteúdo:

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

Pode não funcionar como esperado se chamar o exit num dos dois ficheiros batch. Isso terá de ser testado.

2
2
2
2013-03-21 20:02:36 +0000

Em vez de usar PAUSE (prefiro CHOICE ou TIMEOUT a usar PAUSE quando necessário), pode usar a solução aqui: 886848/how-to-make-windows-batch-file-pause-when-double-click .

Desta forma, se clicar num ficheiro batch ou num link (atalho) a partir do Windows Explorer, pode fazer pausar o programa do ficheiro batch antes de este sair para que possa ver a saída do programa e quaisquer mensagens de erro.

Utilizando CHOICE, pode programar a possibilidade do utilizador seleccionar uma variedade de acções a realizar, e utilizando TIMEOUT pode deixar a janela fechar após um atraso de tempo (sem acompanhamento). Se correr o ficheiro batch a partir de uma janela de comandos, estas pausas podem ser irritantes.

A solução ligada permitir-lhe-á decidir se quer saltar as pausas se o ficheiro batch foi executado a partir de uma janela de comandos.

Pode ler mais no link fornecido, mas o básico é que utiliza a variável de ambiente:

%cmdcmdline%

para determinar se o ficheiro de lote foi executado a partir de uma janela de comandos ou não.

Assim, utiliza-o desta forma:

No ponto em que o ficheiro de lote irá sair, adiciona algum código como este:

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
1
1
2013-03-12 15:30:15 +0000

A melhor maneira que encontrei para contornar isto é chamar os seus ficheiros de lote a partir de outro ficheiro de lote usando o start.

então se normalmente correr um ficheiro chamado go.bat, então criaria um segundo ficheiro de lote chamado algo como go2.bat

o conteúdo de go2.bat seria apenas

start go.bat

a primeira janela fecha-se imediatamente, mas a que corre o seu go.bat permanece aberta

1
1
1
2013-09-24 12:30:12 +0000

Isto funciona para a versão 5.00 do Editor de Registo do Windows.

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

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

Guarde os cmds acima num ficheiro chamado algo como cmdbatfile-open.reg e execute-o!

0
0
0
2017-03-30 08:30:11 +0000

Para utilizadores que utilizam o Windows 10, note que nenhuma das respostas acima funciona actualmente para o Windows 10.

Para Windows 10, se tiver acesso ao script, terá de adicionar o seguinte código no final:

read

Esse código irá esperar por uma entrada antes de fechar.

0
0
0
2019-12-31 21:58:53 +0000

A pergunta do OP está muito mais envolvida do que o que eu precisava, e por isso esta resposta é para outros que vêm aqui à procura de uma forma simples de lançar um programa de linha de comando e manter a janela aberta depois do programa de linha de comando sair.

No meu caso, eu queria correr o NodeJS e manter a janela da consola aberta depois do NodeJS ter parado. Aqui estava a minha solução:

Arquivo: RunNodeJS.bat

@echo off
cd /d c:\
cmd.exe /k cmd /c node

Criei então um atalho para esse ficheiro no meu ambiente de trabalho e fiz duplo clique no atalho para lançar uma consola cmd.exe que executa o comando do nó e permanece aberta depois de este (o comando do nó) sair.

Usei o cmd.exe /k cmd /c node por causa de outra resposta dada aqui.

0
0
0
2017-06-30 03:30:27 +0000

Em resposta ao PSIXO desclassificado - “Esta resposta já estava contemplada na pergunta. - Ro Yo Mi Jan 20 ‘16 às 5:06” – NÃO, NÃO foi. As respostas anteriores foram: “pausa”, o que NÃO funcionou. A resposta da PSIXO foi: “pausa”: “& pause”, o que funciona. Por favor, analise com mais cuidado antes de descer de nível. Corri isto a partir de um prompt IDLE, e funcionou:

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

Por outro lado:

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

NÃO funcionou (o prompt cmd passou por cima, e de facto devolveu um erro (1)). Obrigado à PSIXO pela resposta que precisava. Henry.