C# 在执行PowerPoint自动化时,如何避免RPC_E_CALL_拒绝的异常?
当我的代码尝试创建Microsoft.Office.Interop.PowerPoint.Application的新实例时,有时会出现以下异常:C# 在执行PowerPoint自动化时,如何避免RPC_E_CALL_拒绝的异常?,c#,powerpoint,office-interop,comexception,C#,Powerpoint,Office Interop,Comexception,当我的代码尝试创建Microsoft.Office.Interop.PowerPoint.Application的新实例时,有时会出现以下异常: System.Runtime.InteropServices.COMException (0x80010001): Retrieving the COM class factory for component with CLSID {91493441-5A91-11CF-8700-00AA0060263B} failed due to the foll
System.Runtime.InteropServices.COMException (0x80010001): Retrieving the COM class factory for component with CLSID {91493441-5A91-11CF-8700-00AA0060263B} failed due to the following error: 80010001 Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED)).
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType)
at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType)
at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj)
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
我说有时是因为即使在相同的输入下,它也不会持续发生。此外,它也出现在我的代码的其他部分中(同样缺乏一致性),在这些部分中,我还与PowerPoint自动化API交互
我已经尝试了MSDN本身的解决方案,这似乎是最推荐的解决方案。然而,它似乎没有任何影响,因为我仍然观察到相同的行为
我的问题是:
我以前遇到过这种情况,确实是正确的。这取决于您是否从主线程调用Powerpoint OM(即
此\u AddIn
)。如果是,ppt不应该抛出这些异常。但是,如果您是从另一个线程调用ppt,则必须实现IMessageFilter
,以有效地处理这些windows消息泵错误,因为ppt将主线程对OM的调用优先于其他线程的调用,因此会拒绝调用
另一个警告是,需要进一步的锅炉板代码来处理额外的COMException
s,例如0x800AC472(VBA\u E\u IGNORE)
。有一个例子
因此,完整的解决方案是实现IMessageFilter
,并使用类似于代码的东西来包装OM调用,以便处理可能抛出的其他类型的COMException
因此,对于像他的那样包装代码:
private void TryUntilSuccess(Action action)
{
bool success = false;
while (!success)
{
try
{
action();
success = true;
}
catch (System.Runtime.InteropServices.COMException e)
{
if ((e.ErrorCode & 0xFFFF) == 0xC472)
{ // Excel is busy
Thread.Sleep(500); // Wait, and...
success = false; // ...try again
}
else
{ // Re-throw!
throw e;
}
}
}
}
你可以这样称呼lamdas:
TryUntilSuccess(() =>
{
RegisterFilter(); // register this thread for IMessageFilter use
ppt_app.DoSomething();
UnRegisterFilter(); // unregister this thread for IMessageFilter use
};)
之所以采用这种双管齐下的方法,是因为IMessageFilter
策略比抛出异常更有效,并且能够处理来自应用程序的繁忙消息的次数也更多。但是,在其他时候,您将不得不处理异常,因此您必须同时处理这两种情况
请参见此处,了解包含包装的
嗯 我遇到了同样的问题。也许添加一个线程。在这里和那里睡觉(100)应该有帮助吗?填充图表需要一些时间来更新图表等,因此在添加更多数据之前,您可能需要等待如果没有e,则异常可以在不丢失堆栈跟踪的情况下重新抛出。谢谢,您链接到的第一篇文章非常好地解释了
IMessageFilter
!