TypeLibrary verschiedene Versionen

  • C#

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    TypeLibrary verschiedene Versionen

    Hallo,

    ich arbeite an einem Projekt das per eingebundener TypeLibrary mit Corel Draw kommuniziert. Diese TypeLibrary gibt es in verschiedenen Versionen,
    je nach Corel Draw Version die ich ansprechen möchte.

    Ich möchte mit meinem Programm aber möglichst viele Versionen ansprechen, also verschiedene Versionen der Type Library einbinden.
    Wie ist das möglich?
    die erste Frage ist, warum diese Library? gibt es nicht eine Library, die das kann was du willst aber nicht so viele Abhängigkeiten hat?
    Ansonsten musst du dir halt einen Wrapper schreiben, der jenach vorhandener Version eine andere Library lädt und verwendet. Wenn die API dabei immer gleich bleibt reicht es z.B. beim AssemblyResolve die passende version aufzulösen...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Kannst dann erstmal alles so drinne lassen und musst gucken, dass im Ausgabeverzeichnis keine dieser DLLs vorhanden ist.
    Mach sie z.B. in ein Unterverzeichnis CorelDraw/[VERSION]
    docs.microsoft.com/en-us/dotne…ns/resolve-assembly-loads

    In dem Event-Handler gehste hin und filterst nach e.Name nur dein CorelDraw raus und führst ein manuelles Assembly.LoadFrom aus mit der jeweiligen DLL die du laden möchtest....


    Aber will trotzdem nochmal fragen, was genau nimmst du denn aus CorelDraw, ich kann mir eigt. so direkt nichts vorstellen, was nur CorelDraw kann?
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ah so geht das danke für den Tipp werd ich gleich mal versuchen!

    Kann ich leider nicht genau sagen da es für die Firma ist, aber es werden verschiedene Textbausteine, Bilder, usw. von meinem Programm an Corel Draw gegeben, sodass es ein druckfertiges Dokument wird.
    Ich weiß, dass es viel bessere Lösungen gibt aber es muss Corel Draw sein...

    Edit: Hab grade gesehen, dass keine DLLs im AUsgabeverzeichnis liegt... was nun?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „windowsfan“ ()

    Hmm also zumindest bei Office scheint es zu gehen, wenn du die alte Version importierst und damit programmierst, dass es aufwärtskompatibel ist und anscheinend automatisch die Office COM komponente lädt, hast du das vlt. einfach schon einmal probiert?

    Ansonsten müsstest du für die COM Referenz das Embed bzw Einbetten auf false stellen, dann sollte er eine komplette Interop Assembly anlegen(davon brauchst du dann pro Version eine, das hier sollte auch helfen docs.microsoft.com/de-de/dotne…blies-from-type-libraries). Seit .Net 4.0 kann man diese nämlich in die eigene Applikation einbetten, was dann nur einbettet, was du auch benutzt. Hat natürlich den Vorteil dass es wesentlich kleiner ist, keine extra Assembly benötigt wird. Jedoch kannst somit natürlich keine unterschiedlichen Versionen parallel halten, wenn das COM bereits regelt sollte das jedoch kein Problem darstellen.

    Wenn das alles nicht funktioniert, dann brauchste wohl fast Late-Binding...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    Hmm also zumindest bei Office scheint es zu gehen, wenn du die alte Version importierst und damit programmierst, dass es aufwärtskompatibel ist und anscheinend automatisch die Office COM komponente lädt, hast du das vlt. einfach schon einmal probiert?


    Ja hab ich probiert, aber ich bekomme eine Fehlermeldung. Wenn ich auf dem Ziel PC dann die Version austausche (mit VS -> Refrenezn von anderen Version entfernen -> richtige version hinzufügen) klappt es.


    Hab auch gesehen, dass es eine CorelDraw.tlb gibt, wenn ich diese einbinde, dann hab ich aber das selbe problem bzw. es werden beim einbinden der .tlb datei die zwei referenzen gesetzt die ich vorhin manuell gesetzt habe.
    Für Office täte ich das lösen, indem ich "dreckige" Module schaffe, mit Option Strict Off.
    Und dort die InterOp-Objekte mit CreateObject() GetObject() erstelle.
    Dann hat man da Late-Binding, und solange die zwischen den Versionen nicht die Property-Namen ändern funktioniert das.
    Optimal ist, wenn man in der Debug-Version sauber programmiert, also gegen eine bestimmte Dll, und dann inne Release den Kram switcht auf Strict Off.
    Aber wichtig eben, dass dieser Kram zusammengefasst in einer Datei vorliegt, und sich nicht über alle möglichen Files der Solution verteilt.
    ja ne nix option strict off, da kannste dann gleich Reflection her nehmen, dir MethodInfos etc. holen und diese in typisierte delegaten vorkompilieren und cachen. Damit haste das ganze klarer typisiert, hast ein ekelhaftes Option Strict Off und bekommst sogar mehr performance raus...
    Edit: aber wie gesagt könntest ja erstmal das Embed probieren auszumachen, darauf bist noch gar nicht eingegangen?
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    sorry vergessen aber hab ich probiert. Hab Das Embed für die zwei dlls abgeschalten und dann hat vs mir die zwei dlls in den debug ordner mitgelegt aber was soll ich dann versuchen? Hab auch gesehen, dass es eine CorelDraw.tlb gibt villeich kann ich damit etwas anfangen? wie kann ich diese dann je nach version importieren?
    @jvbsl:

    jvbsl schrieb:

    ...ne nix option strict off, da kannste dann gleich Reflection her nehmen...
    1. Reflection funzt net bei ComObjekten
    2. Beim Compile-Version-Switch beibt der Code unverändert bis auf die Zeilen, wo Com-Objekte erstellt werden. Dassis schon recht komfortabel.


    @windowsfan
    Beispiele...
    jo - finde ich jetzt auch nicht viel. zB diesen hier:
    Überprüfen, ob Excel-Datei bereits geöffnet ist. Ansonsten aktivieren.

    Aber betätige du doch selbst die Forum-Suche nach GetObject und CreateObject

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    1. nicht die .Net Reflection, aber die COM-Reflection...
    2. der Code basiert soweit ich vermute auf dem RuntimeType(zumindest müsste man es in C# so machen, da es kein Strict Off gibt), welcher InvokeMember aufruft, was dann eben die COM Reflection verwendet, da würd ichs lieber direkt aufrufen, oder halt zu C# und dynamic verwenden. Zumindest hat man dann nicht dinge wie "1" + 2 die plötzlich 3 ergeben...

    Kein CreateObject/GetObject...:
    Type.GetTypefromProgId und Activator.CreateInstance


    eine weiter Möglichkeit wäre noch mit IDispatch interface zu beginn die Delegaten ids auslesen und mittels des IUnknown interfaces die nötigen objekte querien und cachen, das wär das performanteste was man vmtl. machen kann(aber auch das aufwendigste)...

    Aber nochmal zurück zu den Dlls...
    Was du versuchen sollst:
    In der Konfiguration, wo er dir die DLL in den Ausgabepfad kopiert, kopier dir die DLL raus und speicher sie in einem expliziten Ordner für die CorelDraw-Version die du referenziert hast.
    Dann gehst du auf deine verschiedenen Rechner mit deinen verschiedenen Versionen und kopierst den kompletten debug ordner. Aber auf dem Zielrechner ersetzt du dann die Interop-Dll jeweils mit der passenden Version für den Zielrechner. Wenn das dann ohne probleme funktioniert, dann weißt du dass du assemblyresolve anwenden kannst...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    na COM speichert die Typinformationen ab, die man abrufen kann, so funktioniert COM über eine vordefinierte ABI, sonst könnte das ja nicht funktionieren...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    hmm - macht mich jetzt nicht wirklich schlauer.
    Also nach meim Vorschlag kann man unter Strict Off eine Zeile wie etwa

    VB.NET-Quellcode

    1. dim xlWorkbook = xlApp.OpenWorkbook(fileFullname)
    unverändert bestehen lassen, wenn sie unter Strict On für eine bestimmte Excel-Version entwickelt wurde und funktioniert hat.
    Und sie wird dann - dank late Binding - für alle Excel-Versionen funktionieren.

    Wie sähe derselbe Vorgang durch Com-Reflection ausgeführt aus?

    VB.NET-Quellcode

    1. xlApp.GetType().InvokeMember("OpenWorkbook", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, xlApp, new object[]{fileFullname});

    Ich weiß ist nicht schön, deshalb aber ja den vorschlag das ganze über Codegenerierung zu machen, bisschen lookups kann man sich da bereits sparen. Und es wäre eben alles typisiert...
    Ansonsten bin ich mir relativ sicher, dass dein Code am Ende denselben Code aufruft wie den von mir geschriebenen.
    Wem die Syntax nicht gefällt und auch keinen Aufwand mit Codegenerierung betreiben will, da sag ich C#+dynamic. Zumindest hat man dann eben nur die bereiche dynamisch, die man haben will...

    Und die HighPerf variante ist wie gesagt um vieles aufwendiger, weshalb ich das nicht einfach schnell mal zusammenstellen kann...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---