Windows XP или более поздняя версия Windows: как запустить пакетный файл в фоновом режиме без отображения окна?

121

Я знаю, что уже ответил на аналогичный вопрос ( Запуск пакетного файла в фоновом режиме при загрузке Windows ), но на этот раз мне нужно запустить пакет:

  • из другой партии,
  • без отображения окна консоли,
  • со всеми аргументами, переданными невидимой партии.

Первый пакет выполняется в окне консоли. Однако я не хочу, чтобы второй пакет (запущенный первым асинхронным способом ) также отображал окно консоли.

Я придумал сценарий VBScript, который делает именно это, и я помещаю его в качестве ответа для других , но если у вас есть другие идеи / решения, не стесняйтесь вносить свой вклад.

Примечание. Многие люди называют окно консоли командного процессора Windows не совсем правильным окном DOS.


Всем спасибо за ответы. Насколько я понимаю, если мне нужно асинхронно вызвать скрипт для работы в невидимом режиме:

  • Из второго скрипта уже в окне консоли, этого start /bдостаточно.
  • Из Windows, без запуска второго окна , мое решение все еще действует.
VonC
источник
Вы запускаете командный файл из ДРУГОГО командного файла? Есть ли у этого уже запущенного командного файла окно?
Oddthinking
Да, этот другой (первый) пакет выполняется в окнах DOS. Однако я не хочу, чтобы вторая партия (запускаемая первой асинхронно) отображала также окна (что могло бы произойти с помощью команды start / b)
VonC

Ответы:

53

Вам нужно, чтобы второй командный файл работал асинхронно? Обычно один командный файл запускает другой синхронно с callкомандой, а второй использует окно первого.

Вы можете использовать start /b second.bat запустить второй пакетный файл синхронно с вашей первой , что разделяет окно вашего первого своего. Если оба командных файла записываются в консоль одновременно, вывод будет перекрываться и, вероятно, не поддается расшифровке. Кроме того, вы захотите поместить команду в конец вашего второго командного файла, иначе вы окажетесь во второй оболочке, когда все будет сделано.exitcmd

P Папа
источник
1
Верный. Я полагал, что start / b откроет новые окна, но если он выполняется из окон DOS, он использует те же окна.
VonC
110

Вот возможное решение:

Из первого сценария вызовите второй сценарий со следующей строкой:

wscript.exe invis.vbs run.bat %*

На самом деле вы вызываете сценарий vbs с помощью:

  • [путь] \ имя вашего скрипта
  • все остальные аргументы, необходимые вашему скрипту ( %*)

Затем invis.vbs вызовет ваш скрипт с помощью метода Windows Script Host Run () , который принимает:

  • intWindowStyle: 0 означает «невидимые окна»
  • bWaitOnReturn: false означает, что вашему первому скрипту не нужно ждать завершения второго скрипта

Вот 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
источник
3
2k просмотров и какой отличный пост + ответ, больше людей должно проголосовать за эту ветку
Рик Токио,
Отличное решение, именно то, что мне нужно.
nikhil
Единственная проблема в том, что это создает процесс с именем cmd.exe, который трудно найти в будущем.
Адитья Гупта
12

Преобразуйте командный файл в exe. Попробуйте Bat To Exe Converter или Online Bat To Exe Converter и выберите вариант, чтобы запустить его как приложение-призрак, то есть без окна.

Роб Кам
источник
3
Возможно, но в данном случае я постараюсь избежать лишних шагов.
VonC
21
Обычно я не такой параноик, но не будет ли глупо позволить кому-то анонимному сгенерировать этот exe для меня? Могут быть введены всевозможные вредоносные программы.
Тобиас
9

Я думаю, что это самое простое и кратчайшее решение для запуска командного файла без открытия окна DOS, это может сильно отвлекать, когда вы хотите запланировать периодический запуск набора команд, поэтому окно DOS продолжает появляться, вот ваше решение , Используйте сценарий VBS для вызова командного файла ...

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

Скопируйте приведенные выше строки в редактор и сохраните файл с расширением .VBS. Отредактируйте имя и путь к файлу .BAT соответственно.

Indago
источник
1
Интересный подход, конечно короче моего решения. +1
VonC
Отличное решение. Читая это, я заметил, что на самом деле нет необходимости использовать Set WshShell = Nothing, у меня все сработало, и у вас может быть еще меньший способ сделать это.
Патрик Бард
7

Вот моя коллекция способов добиться этого - и даже больше - там, где это было возможно, я попытался вернуть также PID запущенного процесса (все связанные сценарии можно загрузить и сохранить с любым именем, которое вы сочтете удобным):

1) Решение IEXPRESS можно использовать даже на старых машинах win 95/98. Iexpress - это действительно древний инструмент, который до сих пор поставляется с Windows, поскольку аргументы принимают только команду и ее аргументы.

Пример использования:

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

2) SCHTASKS - снова принимает только два аргумента - команду и аргументы. Также проверяет, запущен ли он с повышенными разрешениями, и, если возможно, получает PID процесса с помощью WEVTUTIL (доступно в Vista и более поздних версиях, поэтому более новая версия Windows получит PID) команду.

Пример использования:

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

3) 'WScript.Shell' - сценарий является полной оболочкой 'WScript.Shell', и все возможные параметры могут быть установлены через параметры командной строки. Это гибрид jscript / batch, который можно вызывать как летучую мышь.

Пример использования (для получения дополнительной информации распечатайте справку с помощью '-h'):

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

4) Win32_ProcessStartup - снова полная оболочка, и все параметры доступны через аргументы командной строки. На этот раз это гибрид WSF / batch с некоторым Jscript и некоторыми фрагментами кода VBScript, но он возвращает PID запущенного процесса. не скрыто, можно использовать некоторые параметры, такие как координаты X / Y (не применимо для каждого исполняемого файла, но, например, cmd.exe принимает координаты).

Пример использования (для получения дополнительной информации распечатайте справку с помощью '-h'):

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

5) Файл. NET решение . Используются большинство параметров ProcessStartInfo (но в конце я слишком устал, чтобы включать все):

Пример использования (для получения дополнительной информации распечатайте справку с помощью '-h'):

call ProcessStartJS.bat "notepad" -arguments "/A openFile.txt"  -style Hidden -directory "." -title "notepad" -priority Normal
npocmaka
источник
2

В другом вопросе я предложил autoexnt . Это тоже возможно в этой ситуации. Просто установите службу для запуска вручную (т.е. не автоматически при запуске). Если вы хотите запустить свой пакет, измените файл autoexnt.bat, чтобы вызвать нужный пакетный файл, и запустите службу autoexnt.

Пакетный файл для запуска может выглядеть следующим образом (не проверено):

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

Обратите внимание, что запускаемые таким образом командные файлы запускаются от имени системного пользователя, что означает, что у вас нет автоматического доступа к общим сетевым ресурсам. Но вы можете использовать net use для подключения к удаленному серверу.

Вы должны загрузить Windows 2003 Resource Kit, чтобы получить его. Resource Kit также можно установить в других версиях Windows, например в Windows XP.

wimh
источник
1
Интересно, но для этого сценария явный перебор.
VonC
2

Запустите его под другим именем пользователя, используя «runas» или запланировав его под другим пользователем в запланированных задачах Windows.

JosephStyons
источник
Возможно, но не совсем то, что мне нужно (прямой асинхронный вызов в фоновом режиме)
VonC
0

Вы можете запустить свой .bat-файл через .vbs-файл.
Скопируйте следующий код в свой .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 
Винод Челладурай
источник
0

Вы также можете использовать

start /MIN notepad.exe

PS: К сожалению, статус свернутого окна зависит от команды, которую нужно запустить. VG не работают

start /MIN calc.exe
user2928048
источник