1

我正在开发一个 C# 应用程序来自动运行调用多个 VB6 .exe 文件的旧版 VBScript(vbs) 文件。.exe 文件有我需要“响应”的消息框弹出窗口,以允许 VBScript 进程在无人值守的情况下运行。响应需要是 Enter 键。我没有 .exe 文件的来源,也不知道它们的确切用途。我将不胜感激任何帮助...

4

6 回答 6

2

您可能会发现AutoIt很有帮助。

AutoIt v3 是一种类似 BASIC 的免费软件脚本语言,旨在自动化 Windows GUI 和一般脚本。它结合了模拟击键、鼠标移动和窗口/控件操作,以便以其他语言(例如 VBScript 和 SendKeys)不可能或不可靠的方式自动执行任务。

您可以只使用 AutoIt 编程语言开发一些东西,或者您可以从您自己的应用程序中驱动它。我的团队正在使用它,并取得了很好的成功。

于 2010-04-17T19:36:27.583 回答
2

您可以使用 wsh SendKeys()函数。但是,由于您需要确保消息框已激活,因此您还需要在 SendKeys 调用之前立即调用AppActivate() 。

即使这是有问题的,但我已经编写了几个脚本来执行此操作,只要您可以预测消息框何时出现,您就可以发送 [Enter] 键来响应它。

于 2010-04-17T19:37:24.143 回答
1

您可以在 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");
  }
}
于 2010-04-17T22:33:51.147 回答
1

可能想看看使用,

SetWinEventHook PInvoke

检测何时创建对话框。您可以将挂钩指定为全局或特定进程。您可以设置该WINEVENT_OUTOFCONTEXT标志以确保您的代码实际上并未在您挂接的进程中运行。您要查找的事件应该是EVENT_SYSTEM_DIALOGSTART.

一旦您获得了对话框的 hwnd(来自事件挂钩),您就可以使用SendMesssagewithWM_COMMANDWM_SYSCOMMAND摆脱它。

于 2010-04-17T23:25:40.407 回答
0

在花了最后 2 天试图让这个工作后,我终于放弃并决定另一种方法。我正在询问发送到外部进程的数据并筛选导致消息框弹出的条件。感谢所有回答问题的人!

于 2010-04-18T19:19:18.830 回答
0

使用 sendkey 方法,传递键盘键值并继续执行。

于 2010-04-28T01:15:53.393 回答