2010-08-31 2 views
5

J'écris une application pour l'API Peachtree et il doit fonctionner avec n'importe quelle version de l'API. Malheureusement, la DLL de Peachtree 2011 ne peut pas interagir avec Peachtree 2010, et vice versa, même si les deux DLL sont stockées dans le même emplacement et exécutées avec exactement le même code. Je pensais que je devrais être capable de se référer à la DLL par son chemin de fichier, laisser une version spécifique à false, intégrer les types d'interopérabilité à false, et copier local à false et il utiliserait simplement la version de la machine, mais je obtenir une erreur quand je fais cela - "Exception a été levée par la cible d'une invocation."Charger une DLL COM lors de l'exécution?

Existe-t-il un moyen de lier tard la DLL même si c'est COM?

Je peux fournir des exemples de code de ce que vous pensez être utile, mais c'est plus un problème d'installation de projet que n'importe quoi. EDIT: Merci beaucoup à tous pour votre aide. J'ai trouvé ma solution sur une question différente et je l'ai affichée ici.

+0

Habituellement, vous liez la DLL interop au moment de la compilation, et si elle est présente sur le système, elle chargera la DLL COM au moment de l'exécution. Y a-t-il plus d'informations dans l'erreur, ou une exception interne? Y a-t-il un code d'erreur (0xZZZZZZZZ)? Pouvez-vous lier la trace de la pile, ou est-ce donner trop d'informations sur votre application? L'API Peachtree, est-ce COM, ou est-ce une DLL qui se connecte à COM? –

Répondre

7

La liaison tardive aux objets COM nécessite que vous n'ajoutez PAS de référence à la bibliothèque COM à votre projet .NET. , Vous devriez vous utiliser plutôt quelque chose comme ceci pour créer des objets COM:

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

Ensuite, il va se lier à une version de la bibliothèque COM lors de l'exécution.

Voir this article pour plus de détails.

+1

et avec .net 4.0, vous pouvez utiliser le nouveau type 'dynamic' et avoir une liaison d'appel de la méthode late, éliminant le besoin d'ajouter une référence de type http://msdn.microsoft.com/en-us/library/dd264736.aspx –

+0

Une chose que j'aimerais ajouter est que, lorsque vous obtenez l'objet de l'instance de création, vous pouvez le convertir vers le bon type d'interface, donc vous avez toujours une liaison statique, même si la création est en retard. – zumalifeguard

+0

Merci pour votre aide. Vos idées m'ont mis sur le bon chemin. – Yoenhofen

0

C'est la solution

Compile a version agnostic DLL in .NET

Dans le cas où un lien meurt jamais, la clé est de gérer l'événement AppDomain.CurrentDomain.AssemblyResolve comme ci-dessous. L'événement se déclenche à chaque fois qu'une liaison d'assemblage échoue, vous pouvez donc le résoudre vous-même, en corrigeant les conflits de version.

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