Serge
Serge

Reputation: 4036

Defeating 'A program is trying to access email' with SendMessage

I am writing an application in C# that uses Office Outlook Interop (2010; version 14) to access email data through MAPI.

So far I have to manually and repeatedly click Allow in Outlook's "A program is trying to access email address information stored in Outlook" security popup (screenshot at https://i.sstatic.net/gj8to.png).

I tried to write a method to do the clicking automatically, but unsuccessfully. The clicking takes place, but Outlook Interop throws the following exception during the next read operation:

Exception from HRESULT: 0x80004004 (E_ABORT)

Here's an extract from code that uses SendMessage to click on the Allow button:

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

Why does SendMessage not work and how can I make this work?

Upvotes: 2

Views: 2140

Answers (2)

Joshua
Joshua

Reputation: 43270

There's not supposed to be a way to override due to spam abuse.

However, using another thread to hunt down and press the button works.

Please note that SendMessage doesn't work for mouse buttons. You have to use the accessability API or WM_COMMAND.

Oh, and incidentally, don't use delay loops with resending the same message.

Upvotes: 1

SLaks
SLaks

Reputation: 887469

You should use EMAPI, which does not display these warnings.
The Redemption library provides a convenient wrapper.

Upvotes: 2

Related Questions