2010-01-19 5 views
5

Ich habe versucht, eine registrierungsfreie .NET-basierte COM-DLL zu erhalten, aber ohne Erfolg.Konfigurieren von .NET-basierten Komponenten für die registrierungsfreie Aktivierung

  • In Visual Studio 2008 habe ich eine neue C# -Klassenbibliothek hinzugefügt.
  • Ich habe die Optionen 'make assembly COM-visible' und 'register for COM interop' aktiviert.
  • Ich habe eine öffentliche Schnittstelle und Klasse mit einigen Funktionen hinzugefügt.
  • Ich habe eine offensichtliche Abhängigkeit zu meinem C++ Client-Anwendung: #pragma comment (Linker "/ manifestdependency ...

Aber wenn ich meine Anwendung starten erhalte ich‚die Anwendung konnte nicht, weil die Anwendung starten Konfiguration ist falsch '.

Ich habe Microsoft mt-Tool verwendet, um die Manifestdateien der C++ - Clientanwendung und der C# COM-DLL zu extrahieren, und die Informationen in beiden sind identisch (die dependentAssembly in der C++ - Manifestdatei enthält die Derselbe Name und dieselbe Version wie die AssemblyIdentity in der COM-Manifestdatei)

Ich habe auch den auf http://msdn.microsoft.com/en-us/library/eew13bza.aspx beschriebenen Ansatz versucht, aber mit ähnlichen Ergebnissen.

Ähnlich habe ich versucht, einen Verweis auf mein COM-Projekt in "Framework und Referenzen" meiner C++ - Client-Anwendung hinzuzufügen. Die Informationen auf dieser Eigenschaftsseite sahen vielversprechend aus (sie zeigen Optionen wie 'Kopie lokal', 'Abhängigkeiten kopieren' usw. und Eigenschaften wie 'assemblyIdentity'), aber Visual Studio kopiert weder die DLLs noch fügt sie automatisch eine Abhängigkeit zur Manifestdatei hinzu.

Beachten Sie, dass die 'registrierte Variante' funktioniert.

Wer hat irgendwelche Ideen von dem, was ich falsch mache?

Update:

  • Wenn ich eine einfache C++ DLL erstellen und ein Manifest mit dem gleichen Namen und Version meines .NET COM-DLL (gleiche assembly) meine Anwendung einbetten startet in Ordnung. Das Problem liegt also in der Manifestdatei meiner .NET COM DLL.
  • Ich kann das Manifest erfolgreich aus der DLL mit mt -managedassemblyname:... extrahieren und dann das gleiche Manifest mit mt -outputresource:... einbetten, aber das führt auch nicht dazu, dass Windows die Abhängigkeit erfolgreich auflösen kann.

Antwort

4

fand ich die anmeldefreien notwendigen Schritte bekommen .NET COM-Interop-Arbeit selbst :-)

  • Run: mt -managedassemblyname:"myDll.dll" -out:"myDll.manifest"
  • reinigen Manifest (Format bei http://msdn.microsoft.com/en-us/library/eew13bza.aspx sehen). Hauptsächlich musste ich alle Tags außer assemblyIdentity, clrClass und file entfernen (und insbesondere die Laufzeit-, mvid- und Abhängigkeitstags entfernen).
  • Führen Sie mt -outputresource:"myDll.dll" -manifest "myDll.manifest". Im Grunde fügt dies das modifizierte Manifest als Ressource der DLL hinzu. Beachten Sie, dass dies offenbar nicht das gleiche Manifest (Standort) ist! Wenn ich das Manifest mit der Option managedassemblyname erneut extrahiere, erhalte ich immer noch das "alte" Manifest. Wenn ich es mit der Option inputresource extrahiere, bekomme ich die neue.

Ich habe so ziemlich alles dank Windows Vista gefunden. Im Gegensatz zu Windows XP enthält es ein Tool namens sxstrace, das ziemlich detaillierte Informationen über die Probleme bei der Side-by-Side-Ausführung liefert.

+0

Große Lösung! Dies vereinfacht den Installationsprozess erheblich. Danke vielmals! –

+0

Hallo, Ich habe eine C++ - Assembly, die eine Co-Erstellung einer Managed COM-Assembly durchführt, und ich brauche einen ähnlichen Mechanismus. Ich möchte die bestehende .Net-Implementierung umgehen und möchte sie in meine neue Implementierung einbeziehen. Die C++ - Assembly wiederum wird über eine .Net-Exe geladen. Also, wie sollte das Manifest für die C++ Seite entworfen werden? –

-2

Als ich das tat, begann ich mit einer sehr einfachen, grundlegenden Komponente, um die COM-Sachen sortiert zu bekommen. Ich habe auch einen Skript-Client in der anfänglichen Entwicklung verwendet.

Ich habe Visual Studio nicht verwendet, sondern einen Texteditor für den .NET-Code. Ich habe die GUIDs für die Assembly und für die Schnittstellen eingefügt und die Schnittstellen für AutoDispatch markiert.

using System; 
using Interop=System.Runtime.InteropServices; 

namespace Whatever 
{ 
    [Interop.Guid("xxxxxxxx-9120-4283-b972-changethis05")] 
    [Interop.ComVisible(true)] 
    [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] 
    public partial class MyClass : 
    ... 
} 

Ich stellte sicher, dass meine Klasse einen Standardkonstruktor (keine Argumente) hatte.

Ich lief regasm /codebase von Hand, über die Befehlszeile, die .NET-Assembly angeben.

Ich handkodiert das Javascript, um das Objekt zu instanziieren.

Wenn die Dinge verwirrend waren, habe ich die ProgId mit OleView.exe überprüft.

Sobald Sie die grundlegenden Dinge arbeiten, fügen Sie Komplexität allmählich hinzu, bis Sie die funktionierende Lösung erhalten.


Sie können den Ansatz auch aus der anderen Richtung verwenden; vom Kunden. .NET-Assemblys wie System.Random werden bei der Installation von .NET für COM-Interop markiert. Sie können damit sicherstellen, dass Ihre Vorgehensweise in C++ korrekt ist. Instanziieren einer System.Random ProgId ist etwas wie die "Hallo, Welt" von C++ - zu-.NET-via-COM. Wenn das gelingt, dann wissen Sie, dass der grundlegende Ansatz in C++ Sound ist.

+0

Mein COM Interop funktioniert gut. Das Problem ist einfach mit dem registrierungsfreien Teil. Ich kann meine Manifestdatei nicht erfolgreich einbetten, sodass meine Anwendung die Abhängigkeit auflösen kann. Danke für die Antwort. –

Verwandte Themen