Как выполнить команду в уже открытом окне CMD с помощью VBScirpt

Я пытаюсь автоматизировать резервное копирование, которое нужно делать ежедневно. У меня есть программа, работающая в CMD, которая должна быть правильно закрыта перед запуском резервного копирования. Две команды, которые необходимо закрыть: неисправность да (чтобы подтвердить действие)

Затем это окно CMD может быть закрыто, и у меня уже есть файл .bat, написанный для выполнения резервного копирования.

Я никогда не писал VBScripts, кроме очень простых, поэтому мне жаль, если мой вопрос недостаточно ясен.

Идея заключается в том, что с помощью VBScript введите как shutdown {Enter}, так и yes {Enter}, затем закройте это CMD-окно, а затем выполните резервный пакетный файл, который уже настроен для запуска программы CMD после ее завершения резервное копирование.

Операционная система - Windows XP Professional

Спасибо!

Ответ 1

Вы можете попытаться ввести команды программно, отправив нажатия клавиш в виде сообщений Windows в окно CMD, в котором запущена ваша программа.

Я не знаю VBS, возможно, он имеет функцию или функцию, сопоставляемую с функциями API системы PostMessage и/или SendMessage. Было бы здорово, если бы это произошло, особенно если кто-то опубликовал ответ, объясняющий, как их использовать. Тем временем я могу показать вам, как использовать этот метод с помощью утилиты SendMessage в пакетном файле.

В принципе, утилита позволяет отправлять произвольное сообщение Windows в произвольное окно следующим образом:

SendMessage.exe target_specification /message:value /wparam:value /lparam:value 

Я немного позже рассмотрю бит target_specification, а остальные параметры:

  • /message:value - отправленное сообщение, указанное code. В этом случае это будет одно из следующих:

    /message:WM_CHAR
    /message:258
    /message:0x0102
    

    которые все указывают сообщение WM_CHAR.

  • /wparam:value - для сообщения WM_CHAR, это должен быть код посылаемого нажатия клавиши.

    В вашем случае, поскольку ваши команды состоят только из символов ASCII, все коды будут соответствовать кодам ASCII соответствующих символов. Таким образом, вы можете использовать ASCII chart для преобразования символов в ваши команды. s, например, был бы

    /wparam:115
    

    и h

    /wparam:104
    

    и т.д.

    Обратите внимание, что вам также нужно будет отправлять нажатия клавиш Enter. Согласно диаграмма кода управления ASCII, это будет

    /wparam:13
    
  • /lparam:value - вы можете увидеть из страницу руководства WM_CHAR, что LPARAM параметр фактически должен переносить несколько фрагментов информации как одно числовое значение. Однако для вашего конкретного случая достаточно просто запомнить, что этот параметр следует указывать просто как

    /lparam:1
    

Теперь в целевую часть спецификации. Это может быть сложно. Вы узнаете из описания на веб-страницы инструмента, что существуют различные способы указания целевого окна, Однако не каждый метод может работать для вас.

Например, вы можете попробовать указать цель по имени процесса:

/processname:name_of_your_executable

Однако, если вы не вызываете вашу программу напрямую и вместо этого вызываете ее, например. пакетный файл, то программа не будет запускаться в своем собственном окне, но скорее будет заимствовать окно сеанса CMD для хостинга, и поэтому этот метод, скорее всего, не сработает.

Если это действительно так, как вы вызываете программу, вы можете попробовать использовать заголовок окна, чтобы указать цель:

/windowtitle:window_title

Единственное предостережение, о котором следует помнить, состоит в том, что заголовок должен однозначно идентифицировать требуемое окно или нажатия клавиш будут отправляться во все окна, соответствующие указанному типу. Вы можете попытаться идентифицировать заголовок, используя команду title в пакете, вызывающем программу (установка ее перед вызовом программы).

Итак, чтобы подвести итог, вот как выглядит полная резервная копия script (batch script), предполагая, для целей примера, что целевое окно будет указано по его названию:

@ECHO OFF
:: s
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:115 /lparam:1
:: h
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:104 /lparam:1
:: u
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:117 /lparam:1
:: t
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:116 /lparam:1
:: d
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:100 /lparam:1
:: o
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:111 /lparam:1
:: w
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:119 /lparam:1
:: n
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:110 /lparam:1
:: ENTER
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:13 /lparam:1

:: y
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:121 /lparam:1
:: e
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:101 /lparam:1
:: s
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:115 /lparam:1
:: ENTER
SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:13 /lparam:1

:: wait for some time (~3 sec) till the program shuts down, if necessary
PING -n 4 localhost 1>NUL

:: proceed with the back-up
...