我正在开发C#应用程序,以自动运行旧版VBScript(vbs)文件,该文件会调用多个VB6 .exe文件。 .exe文件具有消息框弹出窗口,我需要对其进行“响应”,以允许VBScript进程在无人值守的情况下运行。响应将需要是Enter键。我没有.exe文件的来源,我也不知道它们到底在做什么。我将不胜感激与此有关的任何帮助...
您可能会发现AutoIt有用。
AutoIt v3是类似于BASIC的免费软件专为以下目的而设计的脚本语言自动化Windows GUI和常规脚本。它结合使用模拟按键,鼠标移动和窗口/控件操纵为了以某种方式自动化任务与其他人可能或可靠的语言(例如VBScript和SendKeys)。
您可以仅使用AutoIt编程语言进行开发,也可以从自己的应用程序中进行驱动。我的团队正在使用它,并取得了成功。
您可以使用wsh SendKeys()功能。但是,由于需要确保消息框已激活,因此还需要在SendKeys调用之前立即调用AppActivate()。
即使这是越野车,但我已经编写了几个脚本来完成此操作,只要您可以预测何时出现消息框,就可以发送[Enter]键来对其进行响应。
您可以在C#中执行此操作,而无需某些外部实用程序。诀窍是搜索消息框对话框,然后单击其确定按钮。多次执行此操作需要一个计时器,该计时器不断搜索此类对话框并单击它。将新类添加到您的项目中,然后粘贴以下代码:
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class MessageBoxClicker : IDisposable {
private Timer mTimer;
public MessageBoxClicker() {
mTimer = new Timer();
mTimer.Interval = 50;
mTimer.Enabled = true;
mTimer.Tick += new EventHandler(findDialog);
}
private void findDialog(object sender, EventArgs e) {
// Enumerate windows to find the message box
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero);
GC.KeepAlive(callback);
}
private bool checkWindow(IntPtr hWnd, IntPtr lp) {
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770") return true;
// Got it, send the BN_CLICKED message for the OK button
SendMessage(hWnd, WM_COMMAND, (IntPtr)IDC_OK, IntPtr.Zero);
// Done
return false;
}
public void Dispose() {
mTimer.Enabled = false;
}
// P/Invoke declarations
private const int WM_COMMAND = 0x111;
private const int IDC_OK = 2;
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hWnd, int item);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
样本用法:
private void button1_Click(object sender, EventArgs e) {
using (new MessageBoxClicker()) {
MessageBox.Show("gonzo");
}
}
可能要看使用,
SetWinEventHook PInvoke
检测何时创建对话框。您可以将钩子指定为全局或特定进程。您可以设置WINEVENT_OUTOFCONTEXT
标志,以确保代码在所挂接的进程中并未真正运行。您正在寻找的事件应该是EVENT_SYSTEM_DIALOGSTART
。
一旦获得对话框的对话框(从事件挂钩中获得),就可以将SendMesssage
与WM_COMMAND
或WM_SYSCOMMAND
一起使用来摆脱它。
[花了最后两天的时间来使它工作后,我最终放弃了,并决定了另一种方法。我正在询问发送到外部进程的数据,并筛选导致消息框弹出的条件。感谢所有回答了这个问题的人!
使用sendkey方法,传递键盘键值并继续执行。