COM コンポーネントを使用して Outlook を自動化して電子メールを送信する 32 ビットのレガシー VB6 アプリケーションがあります。要件は、電子メールが Outlook の送信済みアイテム フォルダーに表示される必要があることです。さらに悪いことに、アプリケーションは通常のセキュリティ、警告、または確認メッセージをポップアップすることが許可されていません。
このアプリケーションは、64 ビットの Office が登場するまで問題なく動作していました。32 ビット プロセスが 64 ビット Outlook を自動化する方法はありません。
私が思いついたアイデアは次のとおりです。
COM コンポーネントを、CCW で実行される .NET WCF クライアントと交換します (COM のふりをする .NET)。
この COM コンポーネントは、netTcpBinding を使用して、64 ビット プロセスとして実行される WCF サービスを呼び出します。
次に、WCF サービス (LOCAL SYSTEM として実行) が 64 ビット コンソール アプリケーションをユーザーとして起動し、拡張 MAPI ライブラリを使用して電子メールを送信します。
3 番目のステップの理由は 2 つあります。
メールを送信するように指示すると、MAPI は確認を求めます。拡張 MAPI にはありません。つまり、Microsoft の正しい 64 ビット ヘッダー ファイルを使用して C++ 拡張 MAPI ライブラリをコンパイルし、それを .NET コードから "呼び出す" 必要がありました。
WCF でユーザーの偽装 (大まかに使用される用語) を行うと、レジストリ ハイブの読み込みが正しく行われません。つまり、拡張 MAPI が HKCU からプロファイルを読み込もうとすると失敗します。つまり、基本的に正しいユーザーを "RunAs" するために、新しいプロセスを開始する必要がありました。
これはすべて実際に機能しますが、次の点について説明が必要です。
コマンド ライン パラメータに必要なすべての情報を指定してコンソール アプリケーションを実行すると、MAPI がログインに失敗します。ただし、フォームの OnLoad( ) メソッドでまったく同じコードを使用して、この同じコードを 1 つのフォームを持つ Windows アプリケーションとしてコンパイルすると、成功します。誰でも理由を説明できますか?
現在ログオンしているユーザー (LOCAL SYSTEM ではない) として WCF サービスから "WinForms" アプリケーションを実行するには、正しいトークンを取得するために次の手順を実行しました。
sessionID = (int)WTSGetActiveConsoleSessionId();
ret = WTSQueryUserToken(sessionID, out currentToken);
これを回避する方法はありますか?確かに、WCF の組み込みの偽装を使用する方が良いでしょう。