2010-04-17 57 views
1

我开发一个C#应用程序来自动这就要求几个VB6 .exe文件遗留的VBScript(VBS)文件的运行。 .exe文件具有消息框弹出窗口,我需要'响应'以便允许VBScript进程无人值守运行。回应将需要是Enter键。我没有.exe文件的来源,我不确切知道他们在做什么。 我将不胜感激任何帮助...如何自动响应MSGBOX

回答

0

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

+0

这可能是一个更好,更稳健的方法。 – 2010-04-18 19:38:35

2

你可能会觉得AutoIt有帮助。

AutoIt的V3是一个免费的类似BASIC 脚本语言设计 自动化Windows图形用户界面和一般 脚本。它采用的 模拟击键,鼠标移动 和窗口/控制操作的组合在 为了在某种程度上不 可能或可靠与其它 语言(例如VBScript和 的SendKeys)自动执行任务。

您可以仅使用AutoIt编程语言开发某些东西,也可以从您自己的应用程序中驱动它。我的团队使用这个,并取得了很好的成功。

+0

+1。有趣的工具。 – David 2010-04-17 19:40:59

+0

看起来像它可以工作,但不幸的是,我不能没有通过企业IT审批流程将会介绍此客户端的任何第三方应用程序... – kensy 2010-04-18 19:08:34

2

您可以使用WSH SendKeys()功能。但是,因为你需要确保消息框被激活,你还需要将的SendKeys调用之前立即拨打AppActivate()

即使这是错误的,但我已经写了几个脚本来做到这一点,只要你可以预测消息框何时出现,你可以发送[Enter]键来响应它。

1

您可以在C#中做到这一点,而不需要一些外部工具。诀窍是搜索消息框对话框并单击其确定按钮。多次执行此操作需要一个Timer,它可以继续搜索这样的对话框并将其点击。添加一个新类到您的项目并粘贴此代码:

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"); 
    } 
} 
+0

这是我试图做的事情,但是当消息箱由另一个进程生成时,我无法使它工作。 – kensy 2010-04-18 19:10:10

+0

对,它不适用于其他EXE。除非你能得到这个EXE的主线程ID,Process.Threads和ProcessThread.Id – 2010-04-18 19:20:50

1

可能要看看使用SetWinEventHook的PInvoke正在创建对话框时检测。您可以将挂钩指定为全局或特定进程。您可以设置WINEVENT_OUTOFCONTEXT标志以确保您的代码实际上并未在您所关注的进程中运行。而您要查找的事件应该是EVENT_SYSTEM_DIALOGSTART。

一旦你获得了对话框的hwnd(来自事件钩子),你可以使用WM_COMMAND或WM_SYSCOMMAND的SendMesssage来摆脱它。

0

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