Windows XP ou posterior Windows: Como posso executar um arquivo em lotes em segundo plano sem nenhuma janela exibida?

121

Sei que já respondi a uma pergunta semelhante ( executando o arquivo em lote em segundo plano quando o Windows é inicializado ), mas desta vez eu preciso iniciar um lote:

  • de outro lote,
  • sem nenhuma janela do console exibida,
  • com todos os argumentos passados ​​para o lote invisível.

O primeiro lote é executado em uma janela do console. No entanto, não quero que o segundo lote (iniciado pelo primeiro de maneira assíncrona ) também exiba uma janela do console.

Eu criei um script VBScript que faz exatamente isso e coloquei o script como uma resposta para outras pessoas se referirem , mas se você tiver outras idéias / soluções, sinta-se à vontade para contribuir.

Nota: A janela do console do processador de comandos do Windows é nomeada como janela DOS não correta por muitas pessoas.


Obrigado a todos pelas respostas. Pelo que entendi, se eu precisar chamar assincronamente um script para executar em um modo invisível:

  • A partir de um segundo script já em uma janela do console, start /bé suficiente.
  • No Windows, sem acionar uma segunda janela , minha solução ainda é válida.
VonC
fonte
Você está iniciando o arquivo em lotes a partir de OUTRO arquivo em lotes? Este arquivo em lote já em execução possui uma janela?
Oddthinking
Sim, esse outro (primeiro) lote é executado em uma janela do DOS. No entanto, eu não quero que o segundo lote (lançamento pela primeira vez em um modo assíncrono) exibe também um janelas (que iria acontecer com um comando 'start / b')
VonC

Respostas:

53

Você precisa que o segundo arquivo em lotes seja executado de forma assíncrona? Normalmente, um arquivo em lotes executa outro de forma síncrona com o callcomando, e o segundo compartilha a janela do primeiro.

Você pode usar o start /b second.bat para iniciar um segundo arquivo em lote de forma síncrona do primeiro, que compartilha a janela do primeiro. Se os dois arquivos em lote gravarem no console simultaneamente, a saída será sobreposta e provavelmente indecifrável. Além disso, você desejará colocar um exitcomando no final do seu segundo arquivo em lote ou estará dentro de um segundo cmdshell quando tudo estiver pronto.

P Papai
fonte
1
Corrigir. Eu acreditava que o start / b abriria uma nova janela, mas se executado a partir de uma janela do DOS, ele compartilha as mesmas janelas.
VonC 18/11/08
110

Aqui está uma solução possível:

No seu primeiro script, chame seu segundo script com a seguinte linha:

wscript.exe invis.vbs run.bat %*

Na verdade, você está chamando um script vbs com:

  • o [caminho] \ nome do seu script
  • todos os outros argumentos necessários ao seu script ( %*)

Em seguida, o invis.vbs chamará seu script com o método Windows Script Host Run () , que utiliza :

  • intWindowStyle: 0 significa "janelas invisíveis"
  • bWaitOnReturn: false significa que seu primeiro script não precisa aguardar o término do segundo script

Aqui está o invis.vbs:

set args = WScript.Arguments
num = args.Count

if num = 0 then
    WScript.Echo "Usage: [CScript | WScript] invis.vbs aScript.bat <some script arguments>"
    WScript.Quit 1
end if

sargs = ""
if num > 1 then
    sargs = " "
    for k = 1 to num - 1
        anArg = args.Item(k)
        sargs = sargs & anArg & " "
    next
end if

Set WshShell = WScript.CreateObject("WScript.Shell")

WshShell.Run """" & WScript.Arguments(0) & """" & sargs, 0, False
VonC
fonte
3
2k pontos de vista e que uma grande resposta pós +, mais pessoas devem ser de votar esta discussão
Ric Tokyo
Ótima solução, exatamente o que eu precisava.
Nikhil
O único problema é que isso cria um processo chamado "cmd.exe", difícil de encontrar no futuro.
Aditya Gupta
12

Converta o arquivo em lotes em um exe. Experimente o Conversor Bat To Exe ou o Conversor Online Bat To Exe e escolha a opção para executá-lo como um aplicativo fantasma, ou seja, sem janela.

Rob Kam
fonte
3
Possível, mas tentarei evitar qualquer etapa extra nesse caso.
VonC 18/11/08
21
Normalmente não sou tão paranóico, mas não seria muito estúpido deixar alguém anônimo gerar esse exe para mim? Todos os tipos de coisas maliciosas podem ser injetados.
29412 Tobias
9

Eu acho que essa é a solução mais fácil e mais curta para executar um arquivo em lotes sem abrir a janela do DOS; pode ser muito perturbador quando você deseja agendar um conjunto de comandos para serem executados periodicamente, para que a janela do DOS continue aparecendo, aqui está sua solução . Use um script VBS para chamar o arquivo em lotes ...

Set WshShell = CreateObject("WScript.Shell" ) 
WshShell.Run chr(34) & "C:\Batch Files\ mycommands.bat" & Chr(34), 0 
Set WshShell = Nothing 

Copie as linhas acima para um editor e salve o arquivo com extensão .VBS. Edite o nome do arquivo .BAT e o caminho adequadamente.

indago
fonte
1
Abordagem interessante, certamente mais curta que a minha solução. 1
VonC 15/01/14
Ótima solução. Ao ler isso , notei que não há realmente necessidade de usar Set WshShell = Nothing, funcionou bem para mim e você pode ter uma maneira ainda menor de fazer isso.
Patrick Bard
7

Aqui está minha coleção de maneiras de conseguir isso - e ainda mais - onde era possível. Tentei retornar também o PID do processo iniciado (todos os scripts vinculados podem ser baixados e salvos com o nome que achar conveniente):

1) A solução IEXPRESS pode ser usada mesmo em máquinas antigas win 95/98. O Iexpress é uma ferramenta realmente antiga que ainda é fornecida com o Windows - pois os argumentos aceitam apenas o comando e seus argumentos.

Exemplo de uso:

call IEXPhidden.bat "cmd /c myBat.bat"  "argument"

2) SCHTASKS - Novamente aceita apenas dois argumentos - o comando e os argumentos. Também verifica se foi iniciado com permissões elevadas e, se possível, obtém o PID do processo com WEVTUTIL (disponível no Vista e acima, para que a versão mais recente do Windows receba o PID).

Exemplo de uso:

call SCHPhidden.bat "cmd /c myBat.bat"  "argument"

3) 'WScript.Shell' - o script é um invólucro completo de 'WScript.Shell' e todas as opções possíveis podem ser definidas nas opções de linha de comando.É um híbrido jscript / batch e pode ser chamado de bastão.

Exemplo de uso (para obter mais informações, imprima a ajuda com '-h'):

call ShellRunJS.bat "notepad.exe" -style 0 -wait no 

4) 'Win32_ProcessStartup' - novamente o invólucro completo e todas as opções são acessíveis através dos argumentos da linha de comando. Desta vez, é um híbrido WSF / lote com alguns Jscript e alguns pedaços de código VBScript - mas retorna o PID do processo iniciado. Não oculto Algumas opções como coordenadas X / Y podem ser usadas (não aplicável a todos os executáveis ​​- mas, por exemplo, o cmd.exe aceita coordenadas).

Exemplo de uso (para obter mais informações, imprima a ajuda com '-h'):

call win32process.bat "notepad" -arguments "/A openFile.txt"  -showWindows 0 -title "notepad"

5) o. Solução NET . A maioria das opções das opções ProcessStartInfo são usadas (mas no final eu estava cansada demais para incluir tudo):

Exemplo de uso (para obter mais informações, imprima a ajuda com '-h'):

call ProcessStartJS.bat "notepad" -arguments "/A openFile.txt"  -style Hidden -directory "." -title "notepad" -priority Normal
npocmaka
fonte
2

Na outra pergunta, sugeri autoexnt . Isso também é possível nessa situação. Basta definir o serviço para ser executado manualmente (ou seja, não é automático na inicialização). Quando você deseja executar seu lote, modifique o arquivo autoexnt.bat para chamar o arquivo em lote desejado e inicie o serviço autoexnt.

O arquivo em lote para iniciar isso pode ser assim (não testado):

echo call c:\path\to\batch.cmd %* > c:\windows\system32\autoexnt.bat
net start autoexnt

Observe que os arquivos em lote iniciados dessa maneira são executados como usuário do sistema, o que significa que você não tem acesso aos compartilhamentos de rede automaticamente. Mas você pode usar o net use para se conectar a um servidor remoto.

Você precisa baixar o Windows 2003 Resource Kit para obtê-lo. O Resource Kit também pode ser instalado em outras versões do Windows, como o Windows XP.

wimh
fonte
1
Interessante, mas um exagero apertado para esse cenário.
VonC 18/11/08
2

Execute-o com um nome de usuário diferente, usando "runas" ou agendando-o com um usuário diferente nas Tarefas agendadas do Windows.

JosephStyons
fonte
Possível, mas não exatamente o que eu sou depois (chamada direta assíncrona no fundo)
VonC
0

Você pode executar o arquivo .bat por meio de um arquivo .vbs
Copie o seguinte código no arquivo .vbs:

Dim WshShell
Dim obj
Set WshShell = WScript.CreateObject("WScript.Shell") 
obj = WshShell.Run("C:\Users\file1.bat", 0) 
obj = WshShell.Run("C:\Users\file2.bat", 0)  and so on
set WshShell = Nothing 
Vinod Chelladurai
fonte
0

Você também pode usar

start /MIN notepad.exe

PS: Infelizmente, o status minimizado da janela depende do comando a ser executado. VG não funciona

start /MIN calc.exe
user2928048
fonte