Запустите файл .bat в запланированной задаче без окна

143

У меня есть запланированное задание, которое запускает пакетный скрипт, который запускается robocopyкаждый час. Каждый раз, когда он запускается, на рабочем столе появляется окно с выводом robocopy, которое я не очень хочу видеть.

Мне удалось заставить окно выглядеть свернутым, запустив запланированное задание

cmd /c start /min mybat.bat

но это дает мне новое окно команд каждый час. Я был удивлен этим, учитывая cmd /c«Выполняет команду, указанную в строке, а затем завершается» - я, должно быть, неправильно понял документы.

Есть ли способ запустить пакетный скрипт без его появления окна cmd?

Том Данхэм
источник
Я нашел этот ответ более предпочтительным stackoverflow.com/questions/6568736/…
Efekt

Ответы:

144

Вы можете запустить его без вывода сообщений, используя файл сценария Windows. Метод Run позволяет запускать скрипт в невидимом режиме. Создайте .vbsфайл как этот

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

и запланировать это. Второй аргумент в этом примере устанавливает стиль окна. 0 означает «скрыть окно».

Полный синтаксис метода Run :

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

Аргументы:

  • объект: объект WshShell.
  • strCommand: строковое значение, обозначающее командную строку, которую вы хотите запустить. Вы должны включить любые параметры, которые хотите передать в исполняемый файл.
  • intWindowStyle: Необязательно. Целочисленное значение, указывающее внешний вид окна программы. Обратите внимание, что не все программы используют эту информацию.
  • bWaitOnReturn: необязательно. Логическое значение, указывающее, должен ли скрипт ждать завершения программы, прежде чем перейти к следующему оператору в вашем скрипте. Если установлено значение true, выполнение сценария останавливается до завершения программы, и Run возвращает любой код ошибки, возвращенный программой. Если установлено значение false (по умолчанию), метод Run возвращается сразу после запуска программы, автоматически возвращая 0 (не следует интерпретировать как код ошибки).
splattne
источник
+1, просто написал точно так же
Сэм Коган
Я видел это, прежде чем вы удалили его. Я думаю, что мы оба боты. ;-)
Сплаттне
1
username, честно говоря, я думаю, что Сэм заслуживает этого гораздо больше, чем я. Но все равно спасибо! И не упоминай меня и Джона Скита в одном предложении. Это богохульство! ;-)
Сплаттне
3
На вопрос «Есть ли способ запустить пакетный скрипт, не открывая окно cmd?», Он дает очень прямой ответ: запустите его, используя файл Windows Script.
Марк Мейер
2
@ Ли, я думаю, двойные кавычки необходимы, если ваш путь содержит пробелы.
splattne
58

Вы запускаете это как запланированное задание? Если это так, установите его для запуска под другой учетной записью пользователя, тогда он не будет виден вошедшему в систему пользователю. Если сценарию не нужен сетевой доступ к элементам, для которых требуется проверка подлинности Windows (например, к общим папкам или принтерам), вы можете запустить его как «nt полномочия \ система» и оставить пароль пустым. В Windows 7 просто установите для пользователя значение SYSTEM и нажмите ОК.

(Вы, вероятно, должны использовать реального пользователя, хотя, если вы используете robocopy ...)

JR

Джон Ренни
источник
3
Спасибо - это было меньше хлопот для меня, чем вариант .vbs.
Маккенир
8
Я установил для пользователя «Запуск от имени» значение «СИСТЕМА» (которое впоследствии изменилось на «NT AUTHORITY \ SYSTEM»), и это сработало для меня. Я больше не вижу всплывающее окно CMD при выполнении запланированной задачи. Спасибо!
Райан Стилле
1
+1, это элегантно. Обязательно введите «system» в качестве имени пользователя, тогда win7 сделает все остальное за вас. Обратите внимание, что вы действительно получаете сетевой доступ к Интернету, а не к сетевым ресурсам и тому, что требует аутентификации Windows.
Самсмит
1
Пользователь системы прост и элегантен, отличный СОВЕТ! +1!
Маттео Конта
1
См. Реализация административных моделей с наименьшими привилегиями . Является ли использование Системной учетной записи нарушением политик с наименьшими привилегиями? Если это так, то администраторы должны знать, чтобы не делать этого в большинстве ситуаций.
user34660
29

Просто настройте запланированную задачу как «Запускать, вошел ли пользователь в систему или нет».

Питер Майнл
источник
6
Отлично! Вы даже можете отключить хранилище учетных данных, и тогда это станет более безопасным, чем запуск системы SYSTEM!
Бинки
17

Вы также можете попробовать CHP (Создать скрытый процесс) , который делает именно то, что вы думаете ...

CHP.EXE mybat.bat

Запускается без командного окна. Отлично! Сделано теми же людьми, что и CMDOW, но это более уместно.

rocketmonkeys
источник
Прекрасно работает, когда вам нужно запустить задачу в контексте вошедшего в систему пользователя («Триггер: при подключении к сеансу пользователя», «Запускать задачу как: пользователи»)
Сергей
1
это не встроенный инструмент
JonnyRaa
9

CMDOW - это потрясающий инструмент, который позволяет вам делать множество вещей с окнами из командной строки.

Одна из самых простых вещей - скрыть текущее окно (обычно как первую строку в файле bat) с помощью:

cmdow @ /hid

или начать новый скрытый процесс с

cmdow /run /hid mybat.bat 
itsadok
источник
4
И это, и предложение Rocketmonkeys предполагают загрузку новых инструментов, что означает большую совместимость с настольными компьютерами разных людей. Запекать, используя команды Windows, гораздо лучше.
IanVaughan
Плюс cmdow определяется как «опасный» некоторыми антивирусными программами (это не опасно, но само обнаружение может вызвать некоторые проблемы, если файл cmdow помещен на карантин ...).
Отиель
3
есть еще всплывающая консоль, просто прошить очень быстро.
Бамбук
5

Попробуйте вызвать скрипт с

start /b <command>

источник
1
Это не работает, «Запланированная задача» -> «Состояние» означает «Не удалось запустить», то есть: start / b C: \ file.bat: и: start / b «C: \ file.bat»: но: C: \ file.bat: работает просто отлично.
IanVaughan
1
Потому что startэто не программа, это команда. Вам нужно указать cmdкак программу для запуска и /c start /b <file>как аргумент. Тем не менее, это все равно не сработает, потому что оно все равно создаст консольное окно cmdи высветит черное окно на экране.
Synetech
1
Можно также подтвердить с помощью @Synetech, что это не создаст новое окно, но вам все равно нужно открыть консольное окно, чтобы запустить его. Это действительно удобная команда, но ее нельзя использовать в соответствии с запросом запланированных задач.
Джонатан
5

Вы можете создать ярлык для командного файла, установить ярлык для запуска свернутым (в свойствах ярлыка, вкладка «Ярлык»), а затем настроить задание для запуска ярлыка.

Важное замечание : Вам необходимо указать путь к ярлыку вручную, введя его в текстовое поле «Выполнить» с расширением «.lnk»; если вы просто попытаетесь перейти к нему, он услужливо перенаправит себя к тому, на что указывает ярлык.

Дуг Кавендек
источник
Это не работает на Windows 10 x64, это дает всплывающее окно "Как вы хотите открыть этот файл?"
января
1

Я понимаю, что на этот вопрос уже было дано достаточно хорошее разрешение, которое присуще Windows, и поэтому должно быть наиболее совместимым, и я полностью согласен.

Я также хотел сказать, что я не согласен с комментарием @ splattne (но не с его реальным ответом) - что разрешение в другой упомянутой теме заслуживает доверия. Этот ответ включает запуск сценария от имени другого пользователя (SYSTEM), что в значительной степени эквивалентно предоставлению корневого доступа сценария. Это также не удастся для заданий, таких как ROBOCOPY(на что ссылается Джон Ренни), которые требуют доступа к сети.

Я никогда CMDOWраньше не пробовал , но я хотел бы предложить другое подобное разрешение, которое [хотя и не установлено в Windows], по-прежнему легко переносимо для большинства версий и поставляется как в 32-, так и в 64-битных версиях, и это NirCmd .

NirCmd - очень мощный инструмент, имеющий множество опций, наиболее полезной из которых я лично считаю, что он способен запускать скрытые командные окна, просто выполняя следующее:

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

Из execраздела Справочника по командам NirCmd :

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

Запускает приложение и, при необходимости, указывает один или несколько параметров командной строки для исполняемого приложения. Параметр [show / hide / min / max] указывает, будет ли запущенное приложение видимым или нет. Если указано «скрыть», запущенное приложение не будет видимо пользователю. Если указано «max», окно запущенного приложения будет развернуто. Если указано «min», окно запущенного приложения будет свернуто.

РЕДАКТИРОВАТЬ: я пытался запустить ROBOCOPYзадание и попробовал метод в этом ответе, и он не работал, даже после редактирования прав доступа к сети. Я попытался дважды щелкнуть сценарий и не смог заставить его работать, но смог запустить его только в командной строке с повышенными привилегиями. Я создал ярлык для командного файла и запустил его от имени администратора и смог запустить его, дважды щелкнув по нему, но метод, который я использовал, заключался в том, чтобы запустить его скрытым как SYSTEM (я знаю, я знаю) - но он действительно работает ROBOCOPY, если он имеет правильные права доступа к пакетному файлу.

РЕДАКТИРОВАТЬ 2: По какой-то причине, это не будет работать как SYSTEM (возможно, вещь доступа к сети, на которую ссылались ранее) - я заметил это только после того, как на самом деле работает ROBOCOPYбез флага / L, который в основном просто симуляция и [по-видимому] не на самом деле подключиться к удаленной системе, но когда я запускаю командный файл с наивысшими привилегиями и проверяю скрытый флажок, я все равно могу запустить его как зарегистрированный пользователь в фоновом режиме без отображения командного окна, для чего бы это ни стоило никому ,

rubynorails
источник
-2

Попробуйте ввести команду выхода в конце вашего командного файла. Это должно закрыть командное окно, когда скрипт будет выполнен.

Брайан С. Уилсон
источник
-2

Чтобы скрыть вывод (но не окно), добавьте это в начало вашего пакетного файла:

@echo off
voidstate
источник