2010-08-31 24 views
5

Sto scrivendo un'applicazione per l'API Peachtree e deve funzionare con qualsiasi versione dell'API. Sfortunatamente la dll di Peachtree 2011 non può interagire con Peachtree 2010 e viceversa, anche se le due DLL sono memorizzate nella stessa posizione e funzionano esattamente con lo stesso codice.Carica una DLL COM in fase di runtime?

Ho pensato che dovrei essere in grado di fare riferimento alla dll dal suo percorso file, lasciare una versione specifica su false, inserire i tipi di interoperabilità su false e copiare localmente su false e userebbe solo la versione della macchina, ma io ottenere un errore quando lo faccio - "L'eccezione è stata lanciata dall'obiettivo di un'invocazione".

C'è un modo per associare in ritardo la DLL anche se è COM?

Posso fornire esempi di codice di qualsiasi cosa tu pensi possa essere utile, ma è più un problema di impostazione del progetto che altro.

EDIT: Grazie mille per il vostro aiuto. Ho trovato la mia soluzione sulla domanda di una persona diversa e l'ho pubblicata qui.

+0

Solitamente si collega la DLL di interoperabilità in fase di compilazione e, se è presente nel sistema, verrà caricata la DLL COM in fase di esecuzione. Ci sono altre informazioni nell'errore o un'eccezione interna? C'è un codice di errore (0xZZZZZZZZ)? Puoi collegare la traccia dello stack o è troppo dare informazioni sulla tua app? L'API Peachtree, è COM o è una DLL che si collega a COM? –

risposta

7

L'associazione tardiva agli oggetti COM richiede che NON si aggiunga un riferimento alla libreria COM al progetto .NET. Invece, si dovrebbe utilizzare qualcosa come questo per creare oggetti COM:

Type type = Type.GetTypeFromProgID("Excel.Application") 
    object app = Activator.CreateInstance(type); 

Poi, si legherà a qualsiasi versione della libreria COM in fase di esecuzione.

Vedere this article per ulteriori dettagli.

+1

e con .net 4.0 è possibile utilizzare il nuovo tipo 'dinamico' e avere l'associazione di chiamata del metodo in ritardo, eliminando la necessità di aggiungere un riferimento al tipo http://msdn.microsoft.com/en-us/library/dd264736.aspx –

+0

Una cosa che vorrei aggiungere è che, quando ottieni l'oggetto da creare un'istanza, puoi lanciarlo sul giusto tipo di interfaccia, quindi hai ancora il binding statico, anche se la creazione è in ritardo. – zumalifeguard

+0

Grazie per il vostro aiuto. Le tue idee mi hanno fatto sulla strada giusta. – Yoenhofen

0

Questa è la soluzione

Compile a version agnostic DLL in .NET

Nel caso in cui il collegamento muore mai, la chiave è quello di gestire l'evento AppDomain.CurrentDomain.AssemblyResolve come qui di seguito. L'evento si attiva in qualsiasi momento in cui un binding dell'assembly non riesce, quindi puoi risolverlo da solo, correggendo i conflitti di versione.

using System.Reflection; 

static Program() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) 
    { 
     AssemblyName requestedName = new AssemblyName(e.Name); 

     if (requestedName.Name == "Office11Wrapper") 
     { 
      // Put code here to load whatever version of the assembly you actually have 

      return Assembly.LoadFile("Office11Wrapper.DLL"); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 
Problemi correlati