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

50

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

  1. Colocar uma linha pause após os programas em lote para solicitar que o usuário pressione uma tecla antes de sair
  2. Execução desses arquivos em lote ou outras ferramentas de manipulação de linha de comando (mesmo serviço iniciado, reinicializado, etc. com net start xy ou qualquer coisa semelhante) em cmd.exe (Iniciar - Executar - cmd.exe)
  3. A executar estes programas com cmd /k da seguinte forma: cmd /k myprogram.bat

Mas existem alguns outros casos em que o usuário:

  1. Executa o programa pela primeira vez e não sabe que o programa determinado será executado no Prompt de Comando (Windows Command Processor), por exemplo. ao executar um atalho no menu Iniciar (ou em algum outro lugar), OR
  2. Acha que é um pouco desconfortável executar cmd.exe o tempo todo e não tem tempo / oportunidade de reescrever o código desses comandos em todos os lugares para colocar uma pausa depois deles ou evitar sair explicitamente.

Li um artigo sobre como alterar o comportamento padrão de cmd.exe ao abri-lo explicitamente, com a criação de um < href="http://technet.microsoft.com/pt-br/library/cc779439(WS.10).aspx"> Entrada de execução automática e manipulação de seu conteúdo nesses 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 cmd /d /k como um valor para tentar, mas isso não alterou o comportamento das coisas mencionadas acima ... Ele apenas mudou o comportamento da janela de linha de comando ao abri-la explicitamente (Start-Run-cmd.exe).

Então, como isso funciona? Você pode me dar alguma ideia para resolver esse problema?

    
por Sk8erPeter 04.07.2011 / 17:32

11 respostas

24

Eu tenho uma solução que só pode ser aplicada aos arquivos .cmd e .bat :

Abra regedit e vá para cada um deles:

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

Agora, altere o "Valor da chave padrão" para cmd.exe /k "%1" %* . Agora, todas as janelas de script em lote permanecerão abertas após sua execução.

Observe que isso é como usar cmd.exe /c cmd.exe /k program.bat , o que significa que outra instância do CMD será lançada no pai pai. Não consegui encontrar como sobrescrever o primeiro argumento /c .

Você também pode fazer isso com [exefile] , mas agora ele mostrará uma caixa de console vazia se o executável tiver uma GUI.

    
por 04.07.2011 / 20:05
14

Citar Microsoft :

A console is closed when the last process attached to it terminates or calls FreeConsole.

Em outras palavras, a janela do console do Win32 sempre será fechada quando o último programa em execução sair, e você não poderá alterar isso.

(para programas MS-DOS de 16 bits, o Windows oferece uma opção "Fechar na saída" na caixa de diálogo de propriedades, mas isso não é uma exceção ao comportamento acima: é o processo NTVDM que mantém a janela aberta. esta opção é novamente por programa.)

    
por 04.07.2011 / 19:45
7

Basta abrir um prompt de comando no local do arquivo de lote e digitar manualmente o nome do arquivo de lote para executá-lo nessa janela.

1. Navegue até a pasta onde seu executável reside.  2.Shift-clique direito e selecione "janela de comando a partir daqui"
 3.type no nome do executável e pressione enter
 4. O processo deve ser executado, mas a janela deve permanecer aberta

    
por 21.03.2013 / 15:10
4

cmd.exe /k vai lhe dar problemas com algum lote. Se o lote exit 1 (sem /B ) seu console será fechado. Um truque é usar:

cmd.exe /k cmd /c ...

Para usar isso por padrão para todos os arquivos em lote, defina HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default) e HKEY_CLASSES_ROOT\batfile\shell\open\command\(default) como "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %* .

    
por 06.11.2012 / 14:37
3

Acabei de encontrar uma solução burra depois de ler a resposta de grawity .

Meu caso de uso foi configurar um ambiente de console no trabalho em que todas as soluções mais razoáveis são bloqueadas. Tudo que eu preciso é definir o PATH e configurar alguns aliases doskey e ser despejado no shell.

Minha solução (apenas testada no Win7) como adicionar cmd como a última linha no arquivo em lote. Isso executa um prompt de comando aninhado que herda o ambiente de seu pai. Esse shell filho mantém o processo em lote aberto até você EXIT, ponto no qual o lote não possui processos filho e também sai.

    
por 26.04.2014 / 18:55
2

Em vez de usar PAUSE (prefiro CHOICE ou TIMEOUT para usar PAUSE, quando necessário), você pode usar a solução aqui: 886848 / como-fazer-windows-batch-file-pause-quando-clicou duas vezes .

Dessa forma, se você clicar em um arquivo de lote ou link (atalho) de dentro do Windows Explorer, poderá fazer com que o programa de arquivos em lote pause antes de sair para exibir a saída do programa e quaisquer mensagens de erro.

Usando o comando ESCOLHA, você pode programar a capacidade do usuário de selecionar uma variedade de ações a serem executadas, e o uso de TIMEOUT permite que a janela seja fechada após um atraso de tempo (autônoma). Se você executar o arquivo em lotes de dentro de uma janela de prompt de comando, essas pausas podem ser irritantes.

A solução vinculada permitirá que você decida se deseja pular as pausas se o arquivo em lote foi executado a partir de uma janela do prompt de comando.

Você pode ler mais no link fornecido, mas o básico é que ele usa a variável de ambiente:

%cmdcmdline%

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

Então, você usa assim:

No ponto em que o arquivo de lote será encerrado, você adiciona um 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
    
por 21.03.2013 / 21:02
1

A melhor maneira que encontrei para contornar isso é chamar seus arquivos de lote de outro arquivo de lote usando o início.

então, se você normalmente executa um arquivo chamado go.bat, você criaria um segundo arquivo em lote chamado algo como go2.bat

o conteúdo do go2.bat seria apenas

start go.bat

a primeira janela se fecha imediatamente, mas a que está executando o seu go.bat permanece aberta

    
por 12.03.2013 / 16:30
1

Isso funciona para a versão 5.00 do Editor do Registro do Windows.

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

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

Salve os cmds acima em um arquivo chamado algo como cmdbatfile-open.reg e execute-o!

    
por 24.09.2013 / 14:30
1

Suponha que você tenha dois arquivos em lote que deseja iniciar em sua própria instância e mantenha-se aberto se os executáveis deles saírem. Vamos chamar esses dois lotes A.bat e B.bat .

Agora, para simplificar, você pode ter um arquivo em lote para iniciá-los. Vamos chamá-lo de launch_both.bat com conteúdo:

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

Pode não funcionar como esperado se você chamar exit em um dos dois arquivos em lote. Isso precisará ser testado.

    
por 11.12.2015 / 18:02
0

Para usuários que usam o Windows 10, observe que nenhuma das respostas acima atualmente funciona para o Windows 10.

Para o Windows 10, se você tiver acesso ao script, será necessário adicionar o seguinte código no final:

read

Esse código aguardará uma entrada antes de fechar.

    
por 30.03.2017 / 10:30
0

Em resposta ao PSIXO desatualizado - "Esta resposta já foi abordada na pergunta. - Ro Yo Mi Jan 20 '16 at 5:06" -- Não, não era. As respostas anteriores foram: "pause", que não funcionou. A resposta da PSIXO foi: "& pause", que funciona. Por favor, analise com mais cuidado antes de desclassificar. Eu corri isso de um aviso IDLE, e funcionou:

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

Por outro lado:

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

NÃO funcionou (o prompt do cmd ficou intermitente e, na verdade, retornou um erro (1)). Obrigado à PSIXO pela resposta que eu precisava. Henry.

    
por 30.06.2017 / 05:30