2010-04-17 35 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方法,傳遞鍵盤鍵值並繼續執行。