2011-12-22 10 views
2

私は、Office Outlook Interop(2010;バージョン14)を使用してMAPI経由で電子メールデータにアクセスするアプリケーションをC#で作成しています。SendMessageで「プログラムが電子メールにアクセスしようとしています」

これまでのところ私は手動で繰り返しセキュリティポップアップ(http://i.stack.imgur.com/gj8to.pngでスクリーンショット)「プログラムがOutlookに保存されている電子メールアドレス情報をアクセスしようとしている」Outlookのに許可]をクリックする必要があります。

私はクリックを自動的に行う方法を書こうとしましたが、失敗しました。クリックが行われますが、見通し相互運用機能は次の読み出し動作時に、次の例外がスローされます。

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

これらの警告は表示されないEMAPIを使用する必要があります。
Redemption libraryは、便利なラッパーを提供します。

1

スパム乱用のために上書きする方法はありません。

ただし、他のスレッドを使用してボタンをハントして押しても機能します。

SendMessageはマウスボタンでは機能しません。アクセシビリティAPIまたはWM_COMMANDを使用する必要があります。

ああ、偶然にも、同じメッセージを再送信する際に遅延ループを使用しないでください。

+0

また、マシンがロックされている場合、ターミナルサービスなどでは動作しないことにも注意してください。ログインして、どこかにセッションを表示する必要があります。 – Deanna

+0

一部のアクセシビリティAPIは、サービスセッションから機能します。 WM_COMMANDはそうすることが知られています。 – Joshua

+0

@ジョシュア、私の方法(上記)は別のスレッドで実行されます。長期的には、私はRedemptionを使ってアプリケーションを書き直そうとしますが、今のところこれを実現する必要があります。現在、私のコードではティックボックスがチェックされ、10分のタイムアウトが選択されていますが、拒否がクリックされた場合のように直ちにアプリケーションがクラッシュするのを許可する**が表示されます。あなたは、私が提案したようにWM_COMMANDを使って関数を実装するのを助けてくれますか?大歓迎です! – Serge

関連する問題