2010-10-19 6 views
10

Ich versuche, Registrierung frei COM einzurichten, aber ein kleines Problem, dass ich ein anderes COM-Objekt kann der Client sein.Registration Free Com und DLL-Manifeste

App.exe -----> COM Server/Client-DLL (registriert oder nicht) --------> COM Server DLL (nicht registriert)

Meine Fragen ist, ist es möglich, ein Manifest für die zweite DLL erstellen (COM-Server/Client-DLL)? Ich habe keine Kontrolle über die ausführbare Datei, aber wenn ich das getan habe, funktioniert das, wenn ich ein Client-Manifest für die ausführbare Datei und ein Server-Manifest für die COM-Server-DLL erstelle.

Dies ist die Manifestdatei für die mittlere DLL. Ich habe versucht, es einzubetten und versuchte es extern. Funktioniert immer noch nicht.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity type="win32" 
        name="COMCliSer.dll" 
        version="1.0.0.0" 
    /> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
        name="COMSer.dll" 
        version="1.0.0.0"      
     /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

Bei der weiteren Untersuchung, kann ich das alles so lange arbeiten, wie die mittlere dll auch kostenlos registrieren und die exe hat ein Anwendungsmanifest. Sobald ich die mittlere DLL registriere und das Anwendungsmanifest lösche (ich habe keine Kontrolle darüber, welche EXE meine DLL verwenden wird), hört die ganze Sache auf zu arbeiten.

Wenn die Exe kein Manifest enthält, wird das Manifest der DLL nicht berücksichtigt. Ich kann dies beweisen, indem ich alles für die Arbeit aufstelle. Dann einen Fehler in das Manifest der Versammlung eingeben. Dies zeigt die übliche Meldung:

Prozess konnte nicht erstellt werden: Diese Anwendung konnte nicht gestartet werden, weil die Anwendungskonfiguration nicht korrekt ist. Eine Neuinstallation der Anwendung könnte das Problem lösen.

Wenn ich dann die Anwendung manifestieren fallen, (nicht, wenn auch die CoCreateInstance, weil die Abhängigkeiten nicht berücksichtigt werden) die Anwendung lädt

+0

Warum Sie die Assembly 'comser.dll' fordern? Werden die Informationen zum Zusammenstellungsmanifest zusammengeführt? Es ist viel einfacher, eine Assembly mit einem beschreibenden Namen, z. "Microsoft.VC90.CRT", die DLLs mit unterschiedlichen Namen enthält: "msvcr90.dll". Beim Umgang mit dll-Assemblies wird es schwieriger zu debuggen, da ein einzelnes Manifest nun zwei Zwecken dient: den Inhalt der Assembly den Konsumenten zu beschreiben UND die Abhängigkeiten der DLL in der Assembly zu beschreiben. –

+0

Die Namen wurden geändert, um die Unschuldigen zu schützen! Das sind nicht die richtigen Namen. Dies sind native COM-DLLs und keine .NET-Assemblys. – Steve

+0

Auch, was "funktioniert nicht" zählt als? Werden die exe und die 2. dll geladen und können die 3. Instanz nicht instanziiert werden, oder kann die exe oder 2. dll nicht vollständig geladen werden? Es ist ein guter Schritt, Dinge zu laden, die tatsächlich nicht geladen werden können, da dies bedeutet, dass das System das Manifest sieht und mindestens einen Fehler im System- oder Anwendungsereignisprotokoll protokolliert. Wenn es den Aufruf von CoCreateInstance einfach nicht schafft, kann es das Manifest wahrscheinlich überhaupt nicht sehen. –

Antwort

5

Nur eine Baugruppe Abhängigkeit zum Manifest der Server/Client-DLL hinzufügen, die auf die Punkte com Server dll.

Denken Sie daran, dass Assemblymanifeste sich von Manifesten der Anwendung unterscheiden: Ein Assemblymanifest beschreibt eine Assembly: gibt ihr einen Namen und listet ihre DLLs auf. Ein Anwendungsmanifest ist die eingebettete RT_MANIFEST-Ressource, die die aktuellen Modulabhängigkeiten beschreibt.

Also, in der abschließenden Analyse, würden Sie haben:

  • app.exe, mit einem externen (app.exe.manifest) oder eingebettet RT_MANIFEST eine Abhängigkeit von einer 'acme.clientserver' genannt Montage beschreiben
  • acme.clientserver.manifest beschreibt eine Assembly und listet 'clisrv.dll' als eine Registrierung frei com dll auf.
  • clisrv.dll, mit einem externen (clisrv.dll.2.manifest) oder eingebetteten RT_MANIFEST, beschreibt eine Abhängigkeit von einer Baugruppe genannten acme.server '
  • acme.server.manifest, eine Anordnung zu beschreiben, Auflisten serv .dll als eine Registrierung frei com dll.
  • serv.dll - das kann oder muss nicht wiederum eine Manifest-Auflistung noch abhängiger Baugruppen.

Es ist technisch möglich, die Montage zu rufen durch den Namen der DLL, und verschmelzen sowohl die Montage und dll zusammen manifestieren - das win32 loader dies unterstützt, aber einige Einstellungen, die gültig sind in Anwendungsmanifeste sind nicht gültig in der Montage Manifeste , was dazu führen kann, dass die resultierende Assembly nicht geladen werden kann. Es macht es auch sehr schwierig, digital zu signieren.

WRT die exe muss ein Manifest haben: Normalerweise richtet das Manifest der exe den Standardaktivierungskontext der Prozesse ein. Ich bin nicht 100% sicher, wie Windows sich verhält, wenn die exe kein Manifest hat, aber ich bin mir ziemlich sicher, dass Manifeste in DLLs weiterhin verarbeitet werden.

Das bedeutet, das Problem kommt auf die fehlende Unterstützung der Isolation in CoCreateInstance - aus irgendeinem Grund - standardmäßig - CoCreateInstance sucht nur im Standard-Aktivierungskontext für reg free com Einträge.

Die Art und Weise außer Kraft zu setzen ist Ihren eigenen Aktivierungskontext manuell zu bauen, die zu nennen wären Activation Context API

Die grundlegende Methode:

  • CreateActCtx - eine Aktivierungskontext von Ihrem dlls zu erstellen manifestieren .
  • ActivateActCtx - um den Kontext zu aktivieren
  • CoCreateInstance - wird jetzt den aktuellen Aktivierungskontext nach reg free com-Einträgen durchsuchen.
  • DeactivateActCtx - um den Standardaktivierungskontext wiederherzustellen.

Sie hinzufügen/D ISOLATION_AWARE_ENABLED die meisten Fenster Anrufe zu wickeln, die durch die Aktivierung Kontexten bewirkt werden, aus irgendeinem Grund CoCreateInstance nicht umgebrochen wird:/

+0

ich habe nicht die app.exe.manifest (brauche es nicht, wie die mittlere com dll registriert ist). Ich habe versucht, der mittleren DLL ein Manifest hinzuzufügen, aber ohne Erfolg. – Steve

+0

Haben Sie die mittlere DLL in einem Ressourcen-Editor geöffnet (z. B. Visual Studio) und gesehen, ob es eine RT_MANIFEST-Ressource hat und was ist drin? VS zeigt RT_MANIFESTS immer als Hex an, also müssen Sie es exportieren, um es als Text anzuzeigen. –

+0

Ok, fertig. Die DLL hat zwei RT_Manifests, einer, den ich vermute, wurde vom Compiler (Delphi) dort platziert, der die Windows Common Controls als Abhängigkeit bezeichnet, und die andere 1, die ich hinzugefügt habe, die oben angezeigt wird. – Steve