Windows XP o posterior Windows: ¿Cómo puedo ejecutar un archivo por lotes en segundo plano sin mostrar ninguna ventana?

121

Sé que ya he respondido una pregunta similar ( Ejecutar archivo por lotes en segundo plano cuando se inicia Windows ), pero esta vez necesito iniciar un lote:

  • de otro lote
  • sin ninguna ventana de consola mostrada,
  • con todos los argumentos pasados ​​al lote invisible.

El primer lote se ejecuta en una ventana de consola. Sin embargo, no quiero que el segundo lote (lanzado por el primero de forma asincrónica ) también muestre una ventana de consola.

Se me ocurrió una secuencia de comandos VBScript que hace exactamente eso, y puse la secuencia de comandos como respuesta para que otros la consulten , pero si tiene otras ideas / soluciones, no dude en contribuir.

Nota: La ventana de la consola del procesador de comandos de Windows es nombrada como la ventana de DOS no correcta por muchas personas.


Gracias a todos por las respuestas. Por lo que entiendo, si necesito llamar asíncronamente a un script para que se ejecute en modo invisible:

  • De un segundo script que ya está en una ventana de consola, start /bes suficiente.
  • Desde Windows, sin activar una segunda ventana , mi solución sigue siendo válida.
VonC
fuente
¿Está iniciando el archivo por lotes desde OTRO archivo por lotes? ¿Este archivo de proceso por lotes ya tiene una ventana?
Pensamiento extraño
Sí, este otro (primer) lote se ejecuta en una ventana de DOS. Sin embargo, no quiero que el segundo lote (lanzado por el primero de forma asincrónica) muestre también una ventana (que sucedería con un comando 'inicio / b')
VonC

Respuestas:

53

¿Necesita que el segundo archivo por lotes se ejecute de forma asincrónica? Por lo general, un archivo por lotes ejecuta otro sincrónicamente con el callcomando, y el segundo compartiría la ventana del primero.

Usted puede utilizar start /b second.bat para poner en marcha un segundo archivo por lotes de una forma sincronizada desde su primera ventana que las acciones de su primera. Si ambos archivos por lotes escriben en la consola simultáneamente, la salida se superpondrá y probablemente sea indescifrable. Además, querrás poner un exitcomando al final de tu segundo archivo por lotes, o estarás dentro de un segundo cmdshell una vez que todo esté hecho.

Papi
fuente
1
Correcto. Creía que start / b abriría una nueva ventana, pero si se ejecuta desde una ventana de DOS, sí comparte las mismas ventanas.
VonC
110

Aquí hay una posible solución:

Desde su primer script, llame a su segundo script con la siguiente línea:

wscript.exe invis.vbs run.bat %*

En realidad, estás llamando a un script vbs con:

  • la [ruta] \ nombre de su script
  • todos los otros argumentos necesarios para su script ( %*)

Luego, invis.vbs llamará a su script con el método Windows Script Host Run () , que toma:

  • intWindowStyle: 0 significa "ventanas invisibles"
  • bWaitOnReturn: falso significa que su primer script no necesita esperar a que termine su segundo script

Aquí está 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
fuente
3
2k vistas y qué gran publicación + respuesta, más personas deberían estar votando este hilo
Ric Tokyo
Gran solución, exactamente lo que necesitaba.
nikhil
El único problema es que esto crea un proceso llamado "cmd.exe", que es difícil de encontrar en el futuro.
Aditya Gupta
12

Convierta el archivo por lotes a un exe. Pruebe Bat To Exe Converter o Online Bat To Exe Converter , y elija la opción para ejecutarlo como una aplicación fantasma, es decir, sin ventana.

Rob Kam
fuente
3
Posible, pero intentaré evitar cualquier paso adicional en este caso.
VonC
21
Por lo general, no soy tan paranoico, pero ¿no sería muy estúpido dejar que alguien anónimo genere ese exe para mí? Se pueden inyectar todo tipo de cosas maliciosas.
Tobias
9

Creo que esta es la solución más fácil y más corta para ejecutar un archivo por lotes sin abrir la ventana de DOS, puede ser muy molesto cuando desea programar un conjunto de comandos para que se ejecute periódicamente, por lo que la ventana de DOS sigue apareciendo, aquí está su solución . Use una secuencia de comandos VBS para llamar al archivo por lotes ...

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

Copie las líneas anteriores a un editor y guarde el archivo con la extensión .VBS. Edite el nombre de archivo .BAT y la ruta en consecuencia.

indago
fuente
1
Enfoque interesante, ciertamente más corto que mi solución. +1
VonC
Gran solución Al leer esto , he notado que realmente no hay necesidad de usarlo Set WshShell = Nothing, funcionó bien para mí y puede tener una forma aún más pequeña de hacerlo.
Patrick Bard
7

Aquí está mi colección de formas de lograr eso, y aún más, donde fue posible. Intenté devolver también el PID del proceso iniciado (todos los scripts vinculados se pueden descargar y guardar con el nombre que considere conveniente):

1) La solución IEXPRESS se puede utilizar incluso en máquinas antiguas win 95/98. Iexpress es una herramienta realmente antigua que todavía está empaquetada con Windows, ya que los argumentos solo aceptan el comando y sus argumentos.

Ejemplo de uso:

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

2) SCHTASKS : nuevamente acepta solo dos argumentos: el comando y los argumentos. También verifica si se inició con permisos elevados y, si es posible, obtiene el PID del proceso con WEVTUTIL (disponible desde Vista y superior para que la versión más nueva de Windows reciba el PID).

Ejemplo de uso:

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

3) 'WScript.Shell' : el script es un contenedor completo de 'WScript.Shell' y todas las opciones posibles se pueden configurar a través de las opciones de la línea de comandos. Es un híbrido jscript / batch y se puede llamar como un murciélago.

Ejemplo de uso (para más información imprima la ayuda con '-h'):

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

4) 'Win32_ProcessStartup' : nuevamente el contenedor completo y todas las opciones son accesibles a través de los argumentos de la línea de comando. Esta vez es WSF / híbrido por lotes con algunos códigos Jscript y VBScript, pero devuelve el PID del proceso iniciado. Si el proceso es no ocultas, se pueden usar algunas opciones como las coordenadas X / Y (no aplicable para todos los ejecutables, pero por ejemplo cmd.exe acepta coordenadas).

Ejemplo de uso (para más información imprima la ayuda con '-h'):

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

5) El. Solución neta . Se utilizan la mayoría de las opciones de ProcessStartInfo (pero al final estaba demasiado cansado para incluir todo):

Ejemplo de uso (para más información imprima la ayuda con '-h'):

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

En la otra pregunta sugerí autoexnt . Eso también es posible en esta situación. Simplemente configure el servicio para que se ejecute manualmente (es decir, no automático al inicio). Cuando desee ejecutar su lote, modifique el archivo autoexnt.bat para llamar al archivo por lotes que desee e inicie el servicio autoexnt.

El archivo por lotes para iniciar esto puede verse así (sin probar):

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

Tenga en cuenta que los archivos por lotes iniciados de esta manera se ejecutan como el usuario del sistema, lo que significa que no tiene acceso a los recursos compartidos de red automáticamente. Pero puede usar el uso neto para conectarse a un servidor remoto.

Debe descargar el Kit de recursos de Windows 2003 para obtenerlo. El Kit de recursos también se puede instalar en otras versiones de Windows, como Windows XP.

wimh
fuente
1
Interesante, pero una exageración apretada para este escenario.
VonC
2

Ejecútelo con un nombre de usuario diferente, utilizando "runas" o programándolo con un usuario diferente en Tareas programadas de Windows.

JosephStyons
fuente
Posible, pero no exactamente lo que busco (llamada asíncrona directa en segundo plano)
VonC
0

Puede ejecutar su archivo .bat a través de un archivo .vbs
Copie el siguiente código en su archivo .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
fuente
0

También puedes usar

start /MIN notepad.exe

PD: Desafortunadamente, el estado de ventana minimizado depende del comando que se ejecute. VG no funciona

start /MIN calc.exe
usuario2928048
fuente