How to automate response to msgbox

后端 未结 6 583
遇见更好的自我
遇见更好的自我 2021-01-25 16:08

I am developing a C# application to automate the running of a legacy VBScript(vbs) file which calls several VB6 .exe files. The .exe files have message box pop-ups that I need t

相关标签:
6条回答
  • 2021-01-25 16:24

    Might want to look at using,

    SetWinEventHook PInvoke
    

    to detect when dialogs are being created. You can specify the hook to be global or for a specific process. You can set the WINEVENT_OUTOFCONTEXT flag to ensure that your code isn't actually running in the process you're hooking. And the event you're looking for should be EVENT_SYSTEM_DIALOGSTART.

    Once you've got the hwnd of the dialog (from the event hook), you can use SendMesssage with WM_COMMAND or WM_SYSCOMMAND to get rid of it.

    0 讨论(0)
  • 2021-01-25 16:34

    Using sendkey method, Pass keyboard key value and continue execution.

    0 讨论(0)
  • 2021-01-25 16:39

    You might find AutoIt helpful.

    AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting. It uses a combination of simulated keystrokes, mouse movement and window/control manipulation in order to automate tasks in a way not possible or reliable with other languages (e.g. VBScript and SendKeys).

    You can develop something using only the AutoIt programming language, or you can drive it from your own applications. My team's using this, with good success.

    0 讨论(0)
  • 2021-01-25 16:43

    You can do this in C# without needing some external utility. The trick is to search for the message box dialog and click its OK button. Doing it more than once requires a Timer that keeps searching for such a dialog and clicking it away. Add a new class to your project and paste this code:

    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);
    }
    

    Sample usage:

    private void button1_Click(object sender, EventArgs e) {
      using (new MessageBoxClicker()) {
        MessageBox.Show("gonzo");
      }
    }
    
    0 讨论(0)
  • 2021-01-25 16:50

    You can use the wsh SendKeys() function. However, because you need to ensure the message box is activated, you'll also need to call AppActivate() immediately before the SendKeys call.

    Even this is buggy, but I've written several scripts that do just this, and as long as you can predict when the message boxes will come up, you can send the [Enter] key to respond to it.

    0 讨论(0)
  • 2021-01-25 16:50

    After spending the last 2 days trying to get this working, I finally gave up and decided on another approach. I am interrogating the data that is being sent to the external process and screening it for the conditions that are causing the message box pop-ups. Thanks to everyone who replied with answers!

    0 讨论(0)
提交回复
热议问题