我在大量的Excel工作簿上运行C#脚本,涉及在每个工作簿中调用一个宏;由于错误处理程序,宏有时会生成一个MsgBox,并暂停执行脚本,直到我点击" OK"在MsgBox中。
MsgBox的标题文本是" processSub"中的错误,主文本是"错误(类型不匹配)"。
我想也许我可以找到一个找到所有当前打开的窗口的并发线程,如果找到了MsgBox,点击" OK"。我试图用这样的东西找到窗口:
using System.Diagnostics;
public Process getErrorWindow()
{
Process[] processList = Process.GetProcesses();
foreach (Process process in processList)
{
if (process.MainWindowTitle=="Error in processSub")
{
return process;
}
}
}
但这并没有找到任何东西。当我查看processList[]
时,它似乎只找到主Excel窗口,而不是其VBA代码生成的任何子窗口。有没有办法找到MsgBox并单击其确定按钮?
答案 0 :(得分:2)
您可以使用winapi函数FindWindow按标题和类检索窗口的句柄。将以下代码添加到您的程序中:
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public static IntPtr FindExcelErrorPopup()
{
return FindWindow(null, "Error in processSub");
}
点击按钮:
IntPtr hwnd = FindExcelErrorPopup();
if (hwnd != IntPtr.Zero)
{
SetForegroundWindow(hwnd); // activates the window
SendKeys.SendWait("{ENTER}"); // send ENTER key
}
如果默认按钮不是“OK”,请发送一些TAB笔划以在ENTER之前选择它。
不要忘记为using System.Runtime.InteropServices;
添加DllImport
。
编辑: 对于远程桌面,请尝试以下本机方法:
[DllImport("user32.dll")]
private static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
private const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
private const uint KEYEVENTF_KEYUP = 0x0002;
const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
const uint KEYEVENTF_KEYUP = 0x0002;
然后像这样举起钥匙:
keybd_event(Keys.Enter, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero); // key down
keybd_event(Keys.Enter, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, UIntPtr.Zero); // key up