使用SendMessage击败“程序正在尝试访问电子邮件”

时间:2011-12-22 01:48:24

标签: c# winapi outlook office-interop

我正在用C#编写一个使用Office Outlook Interop(2010;版本14)通过MAPI访问电子邮件数据的应用程序。

到目前为止,我必须手动重复点击Outlook中的“允许”程序正在尝试访问存储在Outlook中的电子邮件地址信息“安全弹出窗口(http://i.stack.imgur.com/gj8to.png处的屏幕截图)。

我尝试编写一种自动点击的方法,但没有成功。单击发生,但Outlook Interop在下一个读取操作期间抛出以下异常:

  

HRESULT的异常:0x80004004(E_ABORT)

以下是使用SendMessage单击“允许”按钮的代码摘录:

private const Int32 BM_CLICK = 0x00F5;
private const Int32 GWL_STYLE = -16;
private const Int32 CB_SETCURSEL = 0x14E;
private const Int32 WM_LBUTTONDOWN = 0x201;
private const Int32 WM_LBUTTONUP = 0x202;

private const string dialogClass = "#32770";
private const string dialogTitle = "Microsoft Outlook";
const string tickBoxTitle = @"&Allow access for";
const string tickBoxClass = @"Button";

private const int ThreadSleepTime = 1000;
private const int ThreadUiSleepTime = 20;

IntPtr popupHandle;
IntPtr tickHandle = IntPtr.Zero;
IntPtr comboHandle = IntPtr.Zero;
IntPtr allowHandle = IntPtr.Zero;
while ((popupHandle = FindWindow(dialogClass, dialogTitle)) != IntPtr.Zero)
{
    // Get object handles
    tickHandle = FindWindowEx(popupHandle, tickHandle, tickBoxClass, tickBoxTitle);
    comboHandle = FindWindowEx(popupHandle, tickHandle, null, null);
    allowHandle = FindWindowEx(popupHandle, comboHandle, null, null);

    // Click on tickbox until the combobox is enabled
    while ((GetWindowLong(comboHandle, GWL_STYLE) & 0x8000000) != 0)
    {
        SendMessage(tickHandle, BM_CLICK, new IntPtr(1), IntPtr.Zero);
        System.Threading.Thread.Sleep(ThreadUiSleepTime);
    }

    // Set dropdown box selection index to 3rd row
    SendMessage(comboHandle, CB_SETCURSEL, 3, 0);
    System.Threading.Thread.Sleep(ThreadUiSleepTime);

    // Click Allow button
    //SendMessage(allowHandle, BM_CLICK, new IntPtr(1), IntPtr.Zero);

    SendMessage(allowHandle, WM_LBUTTONDOWN, IntPtr.Zero, new IntPtr(MakeLParam(5, 5)));
    System.Threading.Thread.Sleep(ThreadUiSleepTime); 
    SendMessage(allowHandle, WM_LBUTTONUP, IntPtr.Zero, new IntPtr(MakeLParam(5, 5)));
}

为什么SendMessage不起作用,我该如何使其工作?

2 个答案:

答案 0 :(得分:2)

您应该使用EMAPI,它不会显示这些警告 Redemption library提供了一个方便的包装器。

答案 1 :(得分:1)

由于滥用垃圾邮件,不应该有一种方法可以覆盖。

然而,使用另一个线程追捕并按下按钮可以正常工作。

请注意,SendMessage不适用于鼠标按钮。您必须使用可访问性API或WM_COMMAND。

哦,顺便说一句,不要使用延迟循环重新发送相同的消息。