none
COM-DLL - Zur Laufzeit eine Fehlermeldung: ist nicht registriert

    Question

  • Hallo, ich habe nun noch eine andere Sache mit einer COM-DLL. Es handelt sich definitiv um eine COM-DLL (habe ich geprüft). Ich habe davon auch schon eine Interop-Com erstellt mit (tlbimp.exe).

    Nun sind in der DLL Klassen und Schnittstellen mit GUID's in der Interop drin. Ich kann die sehen mit NetReflector. Nun habe ich die Interop über Porjekt/Verweise bei mir im Projekt eingebunden.

    in diesem Fall kann ich doch dann die Objekte die in der Interop drin sind einfach bei mir instanziieren, oder?

    Instanziiere ich eine bestimmte Klasse die ich benötige, dann bekomme ich bei kompilieren eine MEldung, das ich die Schnittstelle benutzen soll. Diese gibt es auch in der Interop. Verwende ich diese, bekomme ich von der Laufzeit eine Fehlermeldung, dass die nicht registriert ist.

    Wenn ich die COM-DLL registriere (mit regsvr32) dann gehts komischerweise. Was kan nich da unternehemen?

    Verweis auf dem anderem Diskussionsfaden: http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/c07f4096-068f-472e-9d2b-27ee90745493/

    Thursday, March 29, 2012 9:49 AM

Answers

  • Hallo!

    Wenn ich die Beiträge richtige interpretiere, handelt es sich um eine "echte" COM-dll und keine .NET-COM-dll (da sie mit regsvr32 registriert werden kann).

    Wo soll diese COM-dll verwendet werden?
    Falls sie in einer .net-exe genutzt werden soll, würde ich die Variante mit der Manifest-Datei wählen.

    Mögliche Variante (Early Bindung, registriert während Entwicklung):
    1. COM-dll für die Entwicklung registrieren
    2. COM-dll in References aufnehmen und Eigenschaft "Isolated" auf True stellen. (Das sorgt dafür, dass die Definition in die Manifestdatei der exe aufgenommen wird.)
    3. .net-exe erstellen

    Zum Testen anschließend die COM-dll deregistrieren (regsvr32 /u ...). Die .net-exe sollte funktionieren. Die COM-dll muss (glaube ich zumindest) allerdings im gleichen Verzeichnis (oder Unterverzeichnis) der exe liegen.

    Weitere Variante:
    Falls Late binding ausreicht, ist eventuell die Verwendung der Activation Context API (Microsoft.Windows.ActCtx) eine Möglichkeit.
    (Ich bin mir allerdings nicht sicher, ob das unter C# sinnvoll ist.)


    Für die Verwendung einer COM-dll mit .NET gibt es übrigens auch einige Artikel in der MSDN-Library. Zumindest kamen mir bei meiner Suche nach der RegFree-Verwendung einer .net-com in VBA solche Beiträge unter.
    Beispiele:
    Registration-Free COM Interop

    Registration-Free Activation of COM Components: A Walkthrough

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch

    Thursday, March 29, 2012 2:18 PM
  • Dann sieh dir doch bitte den als Antwort markierten Beitrag von Robert an, und die Links natürlich, die Josef und Thorsten gepostet haben. Das könnte dir weiterhelfen.

    Natürlich könntest Du die COM-DLL auch programatisch aus deine Code registrieren, wiewohl sich mir der Sinn nicht ganz erschließt, denn das würde voraussetzen, dass deine Anwendung über die notwendigen Berechtigungen verfügt. Wenn die Anwendung aber über diese Berechtigungen verfügt, dann ist eine permanente, einmalige COM-Registrierung die bessere Lösung.

    Der Entwickler der Bibliothek könnte - falls es die Architektur und der Sinn der Bibliothek erlauben - entspr. Funktionen exportieren. Dann könntest Du über P/Invoke auf diese exportierten Funktionen zugreifen.  Auch für eine .NET Wrapper-Assembly ist in der Regel die vorherige Registrierung eines COM-Servers notwendig.

    Gruß
    Marcel

    Thursday, March 29, 2012 1:03 PM
    Moderator

All replies

  • Hallo oema,

    Vielen Dank für Deine Frage und Beitrag!

    • Immer für eine Neue Frage einen Neuen Thread aufmachen

    Grundsätzlich ist zu jedem neuen Thema ein eigener Thread zu öffnen, denn dadurch wird die Übersicht gewahrt.

    Ein eigener Thread nutzt der Kommunikation, verhindert Spannungen und Streit und trägt der Übersichtlichkeit in einem Forum bei.

    • Lösungsbeiträge als „Die Antwort“ markieren
      Bitte markieren Sie den Beitrag, der zur Lösung geführt hat, als "Die Antwort". Durch Bewerten eines Beitrags als "Die Antwort" können andere Teilnehmer die Lösung schneller finden. Außerdem können Sie dem Benutzer, der die Antwort eingereicht hat, für seinen Beitrag danken und zur Steigerung der Antwortqualität in der Diskussionsgruppe beitragen.
      [Quelle: Forenregeln]

      Wie bewerte ich einen Beitrag? Um einen Beitrag als hilfreich zu bewerten, klicken Sie in einem beliebigen Beitrag auf Als hilfreich bewerten. Sie können Ihre Stimme nur einmal für einen Beitrag abgeben.
      [Quelle: Häufig gestellte Fragen]

    Danke und Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“beruht, kein technischer Support geleistet werden kannoder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Thursday, March 29, 2012 10:04 AM
    Owner
  • Hallo,

    > Wenn ich die COM-DLL registriere (mit regsvr32) dann gehts komischerweise.

    Das ist nunmal so. Im Normallfall müssen immer folgende Minimalanforderungen erfüllt sein, damit der COM-Zugriff funktioniert: Die COM-(Server)-Bibliothek muss auf dem System existieren und ordentlich registriert worden sein. Da Du die Bibliothek über regsvr32 registrieren kannst, handelt es sich dabei um eine native COM-Bibliothek. Um verwaltete COM-Bibliotheken zu registrieren bräuchtest Du das Tool regasm. Weder in dem einen, noch in dem anderen Fall befindet sich der Code für die Komponente in der Interop-Assembly. Diese enthält lediglich Wrapper für den Zugriff.

    Du versuchst wahrscheinlich unter Visual Studio 2010 und bei eingeschalteter Einbettung von Interop-Typen eine Instanz von [Typ]Class zu erstellen. Das funktioniert nicht, da bei der Einbettung die Verwendung einer Schnittstelle erwartet wird. Hier ein Beispiel, einige Erklärungen und Lösungsansätze:

    using System; using Shell32; // aus: Shell32.dll <== %windir%\system32\shell32.dll (v.6.1.7601.17514, Microsoft Shell Controls and Automation, Windows 7) using System.Reflection; namespace ShellDemoW7 { class Program { static void Main(string[] args) { try { Console.WriteLine("Beliebige Taste drücken, um alle Fenster zu minimieren"); Console.ReadKey(true); // Funktioniert nicht mit "Interop-Typen einbetten" (Standard) // ShellClass shell = new ShellClass(); // Die Schnittstelle hingegen funktioniert mit "Interop-Typen einbetten". // Allerdings muss die auf dem Zielcomputer zur Laufzeit gefundene // shell32.dll eben diese Schnittstelle unterstützen, sonst wird, wie z.B. // auf Windows XP-Systemen, eine System.InvalidCastException ausgelöst, da // die QueryInterface-Operation auf der vorhandenen COM-Komponente ergeben hat, // dass die Komponente diese Schnittstelle nicht unterstützt. Shell temp = new Shell(); temp.MinimizeAll(); // Späte Bindung funktioniert hingegen fast immer // (natürlich muss die COM-Komponente existieren und registriert worden sein): Type shellType = Type.GetTypeFromProgID("shell.application"); object shell = Activator.CreateInstance(shellType); shellType.InvokeMember("ToggleDesktop", BindingFlags.InvokeMethod, null, shell, new object[] { }); } catch (Exception ex) { Console.WriteLine(ex); } Console.ReadKey(); } } }

     


    Marcel

    Thursday, March 29, 2012 11:58 AM
    Moderator
  • Hallo,

    > Wenn ich die COM-DLL registriere (mit regsvr32) dann gehts komischerweise.

    Das ist nunmal so. Im Normallfall müssen immer folgende Minimalanforderungen erfüllt sein, damit der COM-Zugriff funktioniert: Die COM-(Server)-Bibliothek muss auf dem System existieren und ordentlich registriert worden sein. Da Du die Bibliothek über regsvr32 registrieren kannst, handelt es sich dabei um eine native COM-Bibliothek. Um verwaltete COM-Bibliotheken zu registrieren bräuchtest Du das Tool regasm. Weder in dem einen, noch in dem anderen Fall befindet sich der Code für die Komponente in der Interop-Assembly. Diese enthält lediglich Wrapper für den Zugriff.

    Du versuchst wahrscheinlich unter Visual Studio 2010 und bei eingeschalteter Einbettung von Interop-Typen eine Instanz von [Typ]Class zu erstellen. Das funktioniert nicht, da bei der Einbettung die Verwendung einer Schnittstelle erwartet wird. Hier ein Beispiel, einige Erklärungen und Lösungsansätze:

    using System; using Shell32; // aus: Shell32.dll <== %windir%\system32\shell32.dll (v.6.1.7601.17514, Microsoft Shell Controls and Automation, Windows 7) using System.Reflection; namespace ShellDemoW7 { class Program { static void Main(string[] args) { try { Console.WriteLine("Beliebige Taste drücken, um alle Fenster zu minimieren"); Console.ReadKey(true); // Funktioniert nicht mit "Interop-Typen einbetten" (Standard) // ShellClass shell = new ShellClass(); // Die Schnittstelle hingegen funktioniert mit "Interop-Typen einbetten". // Allerdings muss die auf dem Zielcomputer zur Laufzeit gefundene // shell32.dll eben diese Schnittstelle unterstützen, sonst wird, wie z.B. // auf Windows XP-Systemen, eine System.InvalidCastException ausgelöst, da // die QueryInterface-Operation auf der vorhandenen COM-Komponente ergeben hat, // dass die Komponente diese Schnittstelle nicht unterstützt. Shell temp = new Shell(); temp.MinimizeAll(); // Späte Bindung funktioniert hingegen fast immer // (natürlich muss die COM-Komponente existieren und registriert worden sein): Type shellType = Type.GetTypeFromProgID("shell.application"); object shell = Activator.CreateInstance(shellType); shellType.InvokeMember("ToggleDesktop", BindingFlags.InvokeMethod, null, shell, new object[] { }); } catch (Exception ex) { Console.WriteLine(ex); } Console.ReadKey(); } } }

     


    Marcel

    Heißt das also, das ich mit InvokeMember die DLL nicht mehr registrieren muss? Es ist irgendwie seltsam. EIn anderer Kollege in einer anderen Firma entwickelt mit der DLL. Er behauptet, er müßte nichts registrieren. Wie kann das sein?

    Kann ich das registrieren umgehen?

    Thursday, March 29, 2012 12:09 PM
  • > Heißt das also, das ich mit InvokeMember die DLL nicht mehr registrieren muss?

    Nein, das heißt es im Normalfall nicht.

    > Kann ich das Registrieren umgehen? 

    Es gibt die sog. regfree-Verwendung von COM-Komponenten,
    vor kurzem hatte Josef Pötzl in diesem Forum einen Beitrag dazu:

    http://social.msdn.microsoft.com/Forums/en-US/dotnetframeworkde/thread/b25144d7-f99a-4951-b16e-b1e1d1194207

    Gruß
    Marcel

    Thursday, March 29, 2012 12:16 PM
    Moderator
  • Danke für die Info. Ich werde mir das mal ansehen. In diesem Thema bin ich total unerfahren. Also die regasm.exe wird mir auch nicht helfen, die DLL muss registriert sein, sonst geht das also nicht. Könnte ich die DLL auch bei Programmaufruf registrieren und dann bei Programmende wieder deregistrieren? Das wäre eine Möglichkeit.

    Am liebsten wäre mir ohen registrieren, aber da muss ich dann wahrscheinlich mit Mashalling und P/Invoke dran. Das habe ich so noch nie gemacht und muss dann erst mal mein bisheriges Programm umstellen.

    Oder der Entwickler der DLL muss da ran. Kann der in seiner C++ Umgebung die DLL anders gestalten, damit ich diese nicht registrieren muss (ein Assembly oder so etwas?)?? Evtl. wäre es hilfreich dir einmal ein paar Codeschnippsel zu geben, oder die COM-DLL.

    Thursday, March 29, 2012 12:41 PM
  • Dann sieh dir doch bitte den als Antwort markierten Beitrag von Robert an, und die Links natürlich, die Josef und Thorsten gepostet haben. Das könnte dir weiterhelfen.

    Natürlich könntest Du die COM-DLL auch programatisch aus deine Code registrieren, wiewohl sich mir der Sinn nicht ganz erschließt, denn das würde voraussetzen, dass deine Anwendung über die notwendigen Berechtigungen verfügt. Wenn die Anwendung aber über diese Berechtigungen verfügt, dann ist eine permanente, einmalige COM-Registrierung die bessere Lösung.

    Der Entwickler der Bibliothek könnte - falls es die Architektur und der Sinn der Bibliothek erlauben - entspr. Funktionen exportieren. Dann könntest Du über P/Invoke auf diese exportierten Funktionen zugreifen.  Auch für eine .NET Wrapper-Assembly ist in der Regel die vorherige Registrierung eines COM-Servers notwendig.

    Gruß
    Marcel

    Thursday, March 29, 2012 1:03 PM
    Moderator
  • Hallo!

    Wenn ich die Beiträge richtige interpretiere, handelt es sich um eine "echte" COM-dll und keine .NET-COM-dll (da sie mit regsvr32 registriert werden kann).

    Wo soll diese COM-dll verwendet werden?
    Falls sie in einer .net-exe genutzt werden soll, würde ich die Variante mit der Manifest-Datei wählen.

    Mögliche Variante (Early Bindung, registriert während Entwicklung):
    1. COM-dll für die Entwicklung registrieren
    2. COM-dll in References aufnehmen und Eigenschaft "Isolated" auf True stellen. (Das sorgt dafür, dass die Definition in die Manifestdatei der exe aufgenommen wird.)
    3. .net-exe erstellen

    Zum Testen anschließend die COM-dll deregistrieren (regsvr32 /u ...). Die .net-exe sollte funktionieren. Die COM-dll muss (glaube ich zumindest) allerdings im gleichen Verzeichnis (oder Unterverzeichnis) der exe liegen.

    Weitere Variante:
    Falls Late binding ausreicht, ist eventuell die Verwendung der Activation Context API (Microsoft.Windows.ActCtx) eine Möglichkeit.
    (Ich bin mir allerdings nicht sicher, ob das unter C# sinnvoll ist.)


    Für die Verwendung einer COM-dll mit .NET gibt es übrigens auch einige Artikel in der MSDN-Library. Zumindest kamen mir bei meiner Suche nach der RegFree-Verwendung einer .net-com in VBA solche Beiträge unter.
    Beispiele:
    Registration-Free COM Interop

    Registration-Free Activation of COM Components: A Walkthrough

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch

    Thursday, March 29, 2012 2:18 PM
  • Hallo oema,

    Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Thursday, April 05, 2012 12:56 PM
    Owner