Ejecute un archivo .bat en una tarea programada sin una ventana

143

Tengo una tarea programada que inicia un script por lotes que se ejecuta robocopycada hora. Cada vez que se ejecuta, aparece una ventana emergente en el escritorio con la salida de robocopy, que realmente no quiero ver.

Logré hacer que la ventana parezca minimizada haciendo que el trabajo programado se ejecute

cmd /c start /min mybat.bat

pero eso me da una nueva ventana de comando cada hora. Me sorprendió esto, dado cmd /c"Ejecuta el comando especificado por una cadena y luego termina" - Debo haber entendido mal los documentos.

¿Hay alguna manera de ejecutar un script por lotes sin que aparezca una ventana cmd?

Tom Dunham
fuente
Encontré esta una respuesta más preferible stackoverflow.com/questions/6568736/…
Efekt

Respuestas:

144

En su lugar, puede ejecutarlo en silencio usando un archivo de Windows Script. El Método de ejecución le permite ejecutar un script en modo invisible. Crea un .vbsarchivo como este

Dim WinScriptHost
Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\Scheduled Jobs\mybat.bat" & Chr(34), 0
Set WinScriptHost = Nothing

y programarlo El segundo argumento en este ejemplo establece el estilo de la ventana. 0 significa "ocultar la ventana".

Sintaxis completa del método Run :

 object.Run(strCommand, [intWindowStyle], [bWaitOnReturn])

Argumentos:

  • objeto: objeto WshShell.
  • strCommand: valor de cadena que indica la línea de comando que desea ejecutar. Debe incluir cualquier parámetro que desee pasar al archivo ejecutable.
  • intWindowStyle: opcional. Valor entero que indica la apariencia de la ventana del programa. Tenga en cuenta que no todos los programas hacen uso de esta información.
  • bWaitOnReturn: opcional. Valor booleano que indica si el script debe esperar a que el programa termine de ejecutarse antes de continuar con la siguiente instrucción en su script. Si se establece en verdadero, la ejecución del script se detiene hasta que el programa finaliza y Run devuelve cualquier código de error devuelto por el programa. Si se establece en falso (el valor predeterminado), el método Run regresa inmediatamente después de iniciar el programa, devolviendo automáticamente 0 (no debe interpretarse como un código de error).
splattne
fuente
+1, acabo de escribir exactamente lo mismo
Sam Cogan
Lo vi antes de que lo borraras. Supongo que ambos somos bots. ;-)
splattne
1
nombre de usuario, honestamente creo que Sam se lo merece mucho más que yo. ¡Pero gracias de todas maneras! Y no me menciones a mí y a Jon Skeet en la misma oración. Eso es blasfemia! ;-)
splattne
3
A la pregunta "¿Hay alguna manera de ejecutar un script por lotes sin que aparezca una ventana de cmd?", Da una respuesta muy directa: ejecutarlo utilizando un archivo de script de Windows.
Mark Meuer
2
@Lee Supongo que las comillas dobles son necesarias si tu ruta contiene espacios.
splattne
58

¿Estás ejecutando esto como una tarea programada? Si es así, configúrelo para que se ejecute como una cuenta de usuario diferente, entonces no será visible para el usuario conectado. Si el script no necesita acceso de red a elementos que necesitan autenticación de Windows (como archivos compartidos o impresoras), puede ejecutarlo como "nt Authority \ system" y dejar la contraseña en blanco. En Windows 7, simplemente configure el usuario en SISTEMA y presione OK.

(Probablemente tengas que usar un usuario real si estás usando robocopy ...)

JR

John Rennie
fuente
3
Gracias, esto fue menos complicado para mí que la opción .vbs.
mackenir
8
Configuré el usuario "Ejecutar como" en SISTEMA (que luego cambió o NT AUTHORITY \ SYSTEM) y funcionó para mí. Ya no veo la ventana emergente CMD cuando se ejecuta mi tarea programada. ¡Gracias!
Ryan Stille
1
+1, esto es elegante. Asegúrese de ingresar "sistema" como nombre de usuario, luego win7 hace el resto por usted. Tenga en cuenta que SI tiene acceso de red a Internet, simplemente no a recursos compartidos de red y cosas que necesitan autenticación de Windows.
Samsmith
1
El usuario del sistema es simple y elegante, ¡excelente CONSEJO! +1!
Matteo Conta
1
Consulte Implementación de modelos administrativos de privilegios mínimos . ¿El uso de la cuenta del sistema para esto es una violación de las políticas de privilegios mínimos? Si es así, los administradores deben saber no hacer esto en la mayoría de las situaciones.
user34660
29

Simplemente configure la tarea programada como "Ejecutar si el usuario ha iniciado sesión o no".

Peter Meinl
fuente
66
¡Perfecto! ¡Incluso puede deshabilitar el almacenamiento de credenciales y esto termina siendo más seguro que hacer que SYSTEM lo ejecute!
binki
17

También puedes probar CHP (Crear proceso oculto) , hace exactamente lo que piensas ...

CHP.EXE mybat.bat

Se ejecuta sin ventana de comandos. ¡Perfecto! Hecho por las mismas personas que CMDOW, pero esto es más apropiado.

rocketmonkeys
fuente
Funciona perfectamente cuando necesita ejecutar la tarea en el contexto del usuario conectado ("Activador: al conectarse a la sesión del usuario", "Ejecutar tarea como: Usuarios")
Sergei
1
esta no es una herramienta
integrada
9

CMDOW es una herramienta impresionante que le permite hacer muchas, muchas cosas a las ventanas desde la línea de comandos.

Una de las cosas más simples es ocultar la ventana actual (generalmente como una primera línea en el archivo bat) con:

cmdow @ /hid

o comenzar un nuevo proceso oculto con

cmdow /run /hid mybat.bat 
itsadok
fuente
44
Tanto esta como la sugerencia de Rocketmonkeys implican la descarga de nuevas herramientas, lo que significa más compatibilidad con los escritorios de varias personas. El horneado, utilizando comandos de Windows es mucho mejor.
IanVaughan
Además cmdow se detecta como "peligrosos" por algunos programas antivirus (que es no peligrosos, pero la detección puede por sí misma causar algunos problemas si se pone en cuarentena el archivo cmdow ...).
Otiel
3
Todavía hay una consola emergente, solo parpadea muy rápido.
Bamboo
5

Intenta invocar el script con

start /b <command>

fuente
1
Esto no funciona, la Tarea programada-> Estado indica "No se pudo iniciar", es decir: inicio / b C: \ file.bat: y: inicio / b "C: \ file.bat": pero: C: \ file.bat: funciona bien.
IanVaughan
1
Porque startno es un programa, es un comando. Debe especificar cmdcomo programa para ejecutar y /c start /b <file>como argumento. Sin embargo, esto todavía no va a funcionar porque seguirá creando una ventana de consola cmdy mostrará una ventana negra en la pantalla.
Synetech
1
También puede confirmar con @Synetech que esto no creará una nueva ventana, pero aún necesita tener una ventana de consola abierta para iniciarla. Este es, de hecho, un comando útil, pero no se puede utilizar según lo solicitado con las tareas programadas.
JonathanDavidArndt
5

Puede crear un acceso directo al archivo por lotes, configurar el acceso directo para que comience a minimizarse (en las propiedades del acceso directo, pestaña 'Acceso directo') y luego configurar el trabajo para iniciar el acceso directo.

Importante : Deberá especificar la ruta del acceso directo manualmente escribiéndolo en el campo Ejecutar texto, completo con la extensión '.lnk'; si sólo intenta explorar a ella, será amablemente redirigir sí a cualesquiera de los puntos de acceso directo a.

Doug Kavendek
fuente
Esto no funciona en Windows 10 x64, esto muestra una ventana emergente "¿Cómo desea abrir este archivo?"
Jan
1

Me doy cuenta de que esta pregunta ya ha sido respondida con una resolución perfectamente buena que es nativa de Windows y, por lo tanto, debería ser la más compatible, y estoy completamente de acuerdo.

También quería decir que no estoy de acuerdo con el comentario de @ splattne (pero no con su respuesta real), que la resolución en el otro hilo de referencia merece el crédito. Esa respuesta implica ejecutar el script como un usuario diferente (SYSTEM), que es más o menos el equivalente a darle acceso al script root. También fallará para trabajos como ROBOCOPY(como lo menciona John Rennie), que requieren acceso a la red.

Nunca lo he intentado CMDOWantes, pero me gustaría ofrecer otra resolución similar, que [aunque no está instalada de forma nativa en Windows] sigue siendo altamente portátil para la mayoría de las versiones, y viene en versiones de 32 y 64 bits, y eso es NirCmd .

NirCmd es una herramienta muy poderosa que tiene miles de opciones, la más útil de las cuales, personalmente, considero que es su capacidad para iniciar ventanas de comandos ocultas simplemente ejecutando lo siguiente:

c:\path\to\nircmd.exe exec hide "c:\path\to\mybat.bat"

Desde la execsección de la referencia NirCmd comando :

exec [show/hide/min/max] [application + command-line]

Ejecuta una aplicación y, opcionalmente, especifica uno o más parámetros de línea de comandos para la aplicación ejecutada. El parámetro [show / hide / min / max] especifica si la aplicación en ejecución será visible o no. Si se especifica 'ocultar', la aplicación en ejecución no será visible para el usuario. Si se especifica 'max', la ventana de la aplicación en ejecución se maximizará. Si se especifica 'min', la ventana de la aplicación en ejecución se minimizará.

EDITAR: estaba tratando de ejecutar un ROBOCOPYtrabajo y probé el método en esta respuesta, y no funcionó, incluso después de editar los privilegios de acceso a la red. Intenté hacer doble clic en el script y no pude hacerlo funcionar, pero solo pude ejecutarlo bajo un símbolo del sistema elevado. Creé un acceso directo al archivo por lotes y lo ejecuté como Administrador y pude ejecutarlo haciendo doble clic en él, pero el método con el que terminé fue ejecutarlo oculto como SYSTEM (Lo sé, lo sé) - pero funciona ROBOCOPY, por lo que vale, siempre que el archivo por lotes tenga los permisos correctos.

EDITAR 2: por alguna razón, no funcionaría como SYSTEM (probablemente el elemento de acceso a la red al que se hizo referencia anteriormente): solo noté esto después de ejecutar realmente ROBOCOPYsin el indicador / L, que es básicamente una simulación y [aparentemente] no en realidad me conecto al sistema remoto, pero cuando ejecuto el archivo por lotes con los privilegios más altos y verifico la casilla oculta, todavía puedo ejecutarlo como el usuario conectado en segundo plano sin que se muestre una ventana de comandos, para lo que sea que valga para cualquiera .

rubynorails
fuente
-2

Intente poner un comando de salida al final de su archivo por lotes. Esto debería cerrar la ventana de comandos cuando se completa el script.

Brian S. Wilson
fuente
-2

Para ocultar la salida (aunque no la ventana), agregue esto al comienzo de su archivo por lotes:

@echo off
estado nulo
fuente