2012-09-05 20 views
7

Quando il mio codice tenta di creare una nuova istanza di Microsoft.Office.Interop.PowerPoint.Application, a volte ottengo la seguente eccezione:Come evitare le eccezioni RPC_E_CALL_REJECTED quando si esegue l'automazione di PowerPoint?

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) 

dico a volte perché non capita sempre dato anche lo stesso ingresso. Inoltre, si verifica anche (con la stessa mancanza di coerenza) in altre parti del mio codice in cui interagisco anche con l'API di automazione di PowerPoint.

Ho provato la soluzione this da MSDN stessa che sembra essere la soluzione più consigliata. Tuttavia, non sembra avere alcun impatto poiché osservo ancora lo stesso comportamento.

Le mie domande sono:

  1. funziona la soluzione di MSDN per l'automazione di PowerPoint?
  2. Come posso verificare se l'ho applicato correttamente al mio codice?
  3. Qualcuno ha una soluzione alternativa?

Sto usando C#, .NET 4 e PowerPoint 2007.

+0

Sto incontrando lo stesso problema. Forse aggiungere un Thread.Sleep (100) qui e là dovrebbe aiutare? La compilazione di un grafico richiede un po 'di tempo per aggiornare le immagini grafiche ecc. Quindi potrebbe essere necessario attendere prima di aggiungere altri dati. – CodingBarfield

risposta

2

Ho incontrato questo prima e Paul B è davvero corretto. Dipende dal fatto che chiami Powerpoint OM dal thread principale (ovvero This_AddIn) o meno. Se lo sei, ppt non dovrebbe gettare queste eccezioni. Tuttavia, se si sta chiamando ppt da un altro thread, è necessario implementare IMessageFilter per gestire in modo efficiente questi errori del pump dei messaggi di Windows poiché ppt assegna la priorità alle chiamate thread principali all'OM su chiamate da altri thread, da cui i respingi delle chiamate.

Esiste un'altra avvertenza che richiede un ulteriore codice piastra caldaia per gestire ulteriori COMException s come 0x800AC472 (VBA_E_IGNORE). C'è un esempio here.

Quindi, la soluzione completa sia per implementare IMessageFilter e usare qualcosa come sepp2k's codice in cui per avvolgere le chiamate OM al fine di gestire altri tipi di COMException che possono essere lanciate.

Quindi, per il codice involucro come il suo:

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

che si potrebbe chiamare con lamdas come questo:

TryUntilSuccess(() => 
{ 
    RegisterFilter(); // register this thread for IMessageFilter use 
    ppt_app.DoSomething();   
    UnRegisterFilter(); // unregister this thread for IMessageFilter use 
};) 

La ragione di questo duplice approccio è che la strategia IMessageFilter è più efficiente di lanciare eccezioni e sarà più volte che non essere in grado di gestire i messaggi occupati provenienti dall'app. Tuttavia, altre volte si dovrà gestire le eccezioni in modo da avere a che fare sia ...

Vedi qui per il IMessageFilter implementation che comprende involucri

Hth!

Problemi correlati