【问题标题】:How to execute a command in already open CMD window using VBScirpt如何使用 VBScript 在已经打开的 CMD 窗口中执行命令
【发布时间】:2014-01-05 13:31:39
【问题描述】:

我正在尝试自动执行必须每天进行的备份。我有一个在 CMD 中运行的程序,需要在运行备份之前正确关闭该程序。 它需要关闭的两个命令是: 关掉 是(确认操作)

然后可以关闭那个 CMD 窗口,我已经编写了 .bat 文件来执行备份。

除了非常非常简单的之外,我从来没有写过 VBScripts,所以如果我的问题不够清楚,我很抱歉。

想法是这样的——使用VBScript,输入shutdown {Enter}和yes {Enter},然后关闭那个CMD窗口,然后执行备份批处理文件,它已经设置为一旦完成就启动CMD程序备份。

操作系统 - Windows XP Professional

谢谢!

【问题讨论】:

  • 谷歌窗口自动化。你的第一个问题是找到 cmd 窗口。这个程序在这个窗口中运行是你的吗?发出信号关闭自己可能会容易得多
  • 您是否正在启动“在 CMD 中运行的程序”专门准备用于备份的文件?那是控制台程序吗?过程中除了输入“shutdown”和“yes”还有其他交互吗?根据这些问题的答案,管道输入可能会起作用。
  • @AndriyM - 感谢您调查此事。不幸的是,我对控制台或管道一点也不熟悉,而是在 CMD 窗口中运行的程序 - 数据库的监控程序,它从多个客户端接收数据并将其记录到数据库中,并在客户端询问时检索数据。这两个命令是关闭此监控程序所需的唯一命令,从而避免在备份之前损坏数据库。因此,如果管道方法仍然是一种解决方案 - 它是什么,我该如何使用它?再次感谢您!
  • 我可能太仓促了,毕竟管道方法对于您的情况可能不是一个好主意。如果它是一个交互式程序,在执行过程中也应该接受其他命令,那么您确实需要其他东西。

标签: windows batch-file vbscript cmd


【解决方案1】:

您可以尝试通过将击键作为 Windows 消息发送到运行程序的 CMD 窗口来以编程方式输入命令。

我不知道 VBS,也许它有一个或多个函数映射到系统 API 函数PostMessage 和/或SendMessage。如果这样做会很棒,尤其是如果有人发布了解释如何使用它们的答案。同时,我可以通过一个名为SendMessage实用程序在批处理文件中向您展示如何使用此方法。

基本上,该实用程序允许您将任意 Windows 消息发送到任意窗口,如下所示:

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

稍后我将解决 target_specification 位,其他参数是:

  • /message:<i>value</i> – 正在发送的消息,由 code 指定。在您的情况下,它将是以下任何一种:

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

    其中都指定WM_CHAR message

  • /wparam:<i>value</i> – 对于 WM_CHAR 消息,这应该是正在发送的击键代码。

    在您的情况下,由于您的命令仅包含 ASCII 字符,因此所有代码都将匹配相应字符的 ASCII 代码。因此,您可以使用ASCII chart 来转换命令中的字符。例如,s

    /wparam:115
    

    h

    /wparam:104
    

    等等。

    请注意,您还需要发送 Enter 按键。根据ASCII control code chart,应该是

    /wparam:13
    
  • /lparam:<i>value</i> – 您可以从WM_CHAR's manual page 中看到,LPARAM 参数实际上应该将多条信息作为单个数值携带。但是,对于您的具体情况,只需记住该参数应简单地指定为

    /lparam:1
    

现在到目标规范部分。这个可能很棘手。您将从the tool's web page 的描述中了解到指定目标窗口的不同方法。不过,并非每种方法都适合您。

例如,您可以尝试通过进程名称指定目标:

/processname:name_of_your_executable

但是,如果您不直接调用您的程序,而是在例如一个批处理文件,那么程序将不会在自己的窗口中运行,而是会借用托管 CMD 会话的窗口,因此这种方法可能不起作用。

如果这确实是你调用程序的方式,那么你可以尝试使用窗口标题来指定目标:

/windowtitle:window_title

这里要记住的唯一警告是标题必须唯一标识所需的窗口,否则击键将发送到与指定标题匹配的所有窗口。您可以尝试通过在调用程序的批处理中使用title 命令来使标题唯一化(在调用程序之前设置它)。

因此,总而言之,以下是完整备份脚本(batch 脚本)的样子,假设出于示例的目的,目标窗口将由其标题指定:

@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
...

【讨论】:

  • 哇。非常感谢!我可以看到我现在非常接近完成这项工作!我做了你上面告诉我的一切,学到了很多关于 WM_CHAR 的知识。现在,由于某种原因,当我在 .bat 命令中使用 SendMessage.exe /windowtitle:"My Title" /message:WM_CHAR /wparam:115 /lparam:1 时,它根本不会在窗口中键入任何字母。但是,如果我输入 SendMessage.exe /windowtitle:"My Title" /message:16 - 我会收到一条消息,警告我我即将强制关闭窗口。
  • 据此我得出结论,窗口的定位不是问题 - 它发现它很好,但看起来我在使用 WM_CHAR 命令时做错了。通过查看 Microsoft 网站上的 WM_CHAR,我读到了一些关于它使用 UTF-16 字符编码的内容,这让我想也许我应该使用一些不同的数字来表示字母?
  • 抱歉,昨晚没机会看到您的回复。不过,目前这里没什么好说的。我在 Windows 7 x64 下进行了测试。我在“干净”cmd.exe 会话上尝试了SendMessage(即我刚刚运行cmd.exe,设置标题,然后发送WM_CHARs)并在其中带有ftp.exe 的CMD 会话(cmd.exe,设置标题,ftp.exe 来自它,它在同一个窗口内启动了自己的会话,然后我发送了 WM_CHARs)。两项测试均成功。我不知道,也许您正在使用 DOS(实际 DOS)程序,它无法接收任何 WM_CHAR。恐怕无法在我的 Win 7 下验证。
  • 虽然一个想法,但我自己也准备好在我第一次开始使用 SendMessage 用于我自己的目的时使用它。 (和你一样,我用它来发送 WM_CHAR。它们很可能对我很有效,因为我的目标是一个 GUI 程序。)你可以尝试用两条消息替换每个 WM_CHAR,WM_KEYDOWNWM_KEYUP,发送以该顺序。 (是的,您需要阅读更多内容,对此感到抱歉。)
  • 我将自己尝试这种方法,为了我自己的教育以及能够尝试为你想出一个替代脚本,只是不能保证它会发生很快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 2022-01-04
  • 2011-07-24
相关资源
最近更新 更多