我正在尝试使用COM自动化Outlook,并且在尝试使用MAPI方法时,Outlook在任意点崩溃时遇到了严重问题(例如,Outlook.Recipient r = MAPI.CreateRecipient(“me@there.com”)) 。
建议的一个解决方案是使用Marshal.GetActiveObject()而不是新的Outlook.Application()。
这似乎工作正常,但我遇到了一个非常奇怪的问题 - 代码启动Outlook的副本并尝试获取应用程序对象,但调用Marshal.GetActiveObject抛出System.Runtime.InteropServices.COMException异常而Outlook是活跃的应用程序(有焦点)。
如果我运行以下代码,那么try会反复失败。
但是,如果我点击ALT-TAB或点击任何地方使Outlook不再是活动应用程序,则代码立即成功。
有什么想法吗?如果不这样做,是否有人会将代码放在前景上,所以代码会成功?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
namespace MAPI_Repro
{
class FakeTest
{
public Outlook.Application oApp;
public Outlook.NameSpace MAPI;
public void DoTest(){
if (Process.GetProcessesByName("OUTLOOK").Count() == 0)
{
var process = Process.Start(new ProcessStartInfo("outlook.exe"));
}
while (Process.GetProcessesByName("OUTLOOK").Count() == 0)
{
Thread.Sleep(100);
}
bool success = false;
while (!success)
{
Debug.WriteLine("Waiting for Marshal.GetActiveObject");
try
{
// This FAILS while Outlook is the active application.
// As soon as you hit ALT-TAB or click another app, this succeeds.
oApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
success = true;
Debug.WriteLine("SUCCESS");
}
catch (System.Runtime.InteropServices.COMException exp)
{
Debug.WriteLine("FAILED " + exp);
}
Thread.Sleep(100);
}
MAPI = oApp.GetNamespace("MAPI");
MAPI.Logon("", "", Missing.Value, Missing.Value);
}
}
}