vs und externes manifest verwenden
-
hallo,
ich habe ein einfaches c program(COM-Client), das auf eine COM c# DLL zugreifen soll ohne Registry. das ganze heisst auch side by side konfiguration und benutzt manifests
ich habe mich nach der Anleitungen in folgende Links orientiert:
http://www.shafqatahmed.com/2009/04/interop-using-a-net-based-component-from-a-non-net-platform-using-registry-free-com.html
oder
http://msdn.microsoft.com/en-us/library/ms973915.aspxich habe das C-program mit vs 2010 erstellt -> Client2.exe
... int _tmain(int argc, _TCHAR* argv[]) { CoInitializeEx(0, COINIT_MULTITHREADED); { IQuoteProviderPtr ptr; HRESULT hr = ptr.CreateInstance(__uuidof(QuoteProvider)); if (SUCCEEDED(hr)) { cout << ptr->GetAFunnyQuote() << endl; } else { cout << "COM Error:" << endl; ErrorDescription(hr); } char c; cin >> c; } CoUninitialize(); return 0; }
und hier ist das mifestdatei Client2.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type = "win32" name = "client2" version = "1.0.0.0"/> <description>Sample Manifest Test Application</description> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <!-- <requestedExecutionLevel level="requireAdministrator" /> --> <requestedExecutionLevel level="asInvoker" /> <!-- <requestedExecutionLevel level="highestAvailable" /> --> </requestedPrivileges> </security> </trustInfo> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="QuoteSource" version="1.0.0.0"/> </dependentAssembly> </dependency> </assembly>
wenn ich die exe starte wird der manifest file ignoriert. wie bringe die exe oder vs den externen manifest zu verwenden.
der manifest liegt auch im exe verzeichnis.was mache ich falsch?
ich bin schon ein paar tage damit beschäftigt aber ohne erfolg und habe verschiedenes ausprobiert in visual studio projekt eigenschaften
-
Du willst ein COM-Komponente in C mit einer COM-Komponente in C# verdrahten und schreibst dafür einen extrem Windows-spezifischen Win-API-C++ Schnipsel, behauptest aber, es sei ein C-Programm. Du hast dabei das Problem, dass der Compiler mit diesem Windows-spezifischen Teil nicht tut was du erwartest.
Ich fasse zusammen:
etwas C, etwas C#, etwas Win-API, etwas MS-Compiler-Problematik. Für alle vier Bereiche gibts ein eigenes Forum hier.Was hat das noch gleich mit Standard-C++ zu tun???
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ (auch C++0x und C++11) in das Forum Compiler- und IDE-Forum verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Du hast hier ein Manifest, welches eine .NET-Referenz drin hat... das brint Dir nichts bei COM-Referenzen
Du musst schon ein Manifest erzeugen. weclhes die COM-Referenz hat...
Für .NET-COM sieht der Befehl dazu so aus um ein passenden Manifest zu erzeugen (bzw. eben der COM-Teil!):
mt.exe -managedassemblyname:netlib.dll -nodependency -out:netlib.dll.manifest
Für normales COM/OCX geht es so:
mt.exe -tlb:mycomlib.ocx -dll:mycomlib.ocx -out:mycomlib.ocx.manifest
-
Hallo,
ich benutze schon einen manifest für die COM .net Dll: QuoteSource.manifest<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="win32" name="QuoteSource" version="1.0.0.0" /> <clrClass clsid="{8B351C03-A423-4D50-A19C-7672638FE887}" progid="QuoteSource.QuoteProvider" threadingModel="Both" name="QuoteSource.QuoteProvider"> </clrClass> </assembly>
und das die COM .Net DLL
using System; using System.Collections.Generic; using System.Text; namespace QuoteSource { [System.Runtime.InteropServices.Guid("4362B3CA-B747-4F67-B8DA-079EEC0F68F6")] public interface IQuoteProvider { string GetAFunnyQuote(); } [System.Runtime.InteropServices.Guid("8B351C03-A423-4D50-A19C-7672638FE887")] public class QuoteProvider : IQuoteProvider { private string[] _quotes = { "Doing nothing is very hard to do...you never know when you're finished. - Leslie Nielsen", "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up. - Muhammad Ali", "I like work: it fascinates me. I can sit and look at it for hours. - Jerome K Jerome", "The easiest job in the world has to be coroner. Surgery on dead people. What's the worst thing that could happen? If everything went wrong, maybe you'd get a pulse.- Dennis Miller", "My father taught me to work; he did not teach me to love it.- Abaham Lincol", "Hard work never killed anybody, but why take a chance?- Edgar Berger", "My advice to you is get married: if you find a good wife you'll be happy; if not, you'll become a philosopher.- Socrates", "Love is temporary insanity curable by marriage.- Ambrose Bierce" }; public QuoteProvider() { } public string GetAFunnyQuote() { Random rand = new Random(); return _quotes[rand.Next(_quotes.Length-1)]; } } }
ich habe es getestet mit manifest als internen und als externen aber ohne Erfolg
aber trotzdem findet der Client die DLL nicht.
ich habe den Eindruck dass der Client seinen Manifest ignoriert und nicht nach dem Verweis auf die Dll sucht! das glaube ich weil es zu keine Side by Side Konfigurationsfehler kommt wenn ich die DLL aus dem verzeichnis lösche
-
WO hast Du es eingebettet? In die DLL oder die EXE?
Du musst es in die EXE reinpacken!
-
ah!!
das zweite manifest "QuoteSource.manifest"
was ich gerade gepostet habe, habe ich in der DLL eingebettet.
laut Microsoft Anleitung http://msdn.microsoft.com/en-us/library/ms973915.aspx
soll das zqweite manifest in der DLL eingebetett und das erste manifest "Client2.exe.manifest" als extern im gleichen verzeichniss wo der Client.exe abgelegt ist
oder liege ich falsch??
-
Erzeuge mal eine C# WinForms-Anwendung. Dann füge die Referenz auf die registruerte COM-Bibliothek hinzu. Dann setze bei den Referenzen das "Isolation/Local" auf "true". Und dann schaur Dir mal das Manifest der *EXE* an. genau so muss auch Dein Manifest Deiner *EXE* ausschauen!
-
ich habe eine winforms c# Anwendung erstellt und habe die QuoteSource.dll als Verweis hinzugefügt. tlb kann ich nicht als verweis hinzufügen. kommt eine Fehlemeldung und einen Hinweis dass ich die DLL benutzen soll. Bei der Eigenschaften vom Verweis vermisse ich die Einstellung "Isolation/Local". ich habe nur lokale kopie = True und Interop-Typen einbetten = false unf andere ...
und der manifestdatei Manifest_Test.vshost.exe.manifest sieht so aus
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly>
der manifest enthält keinen verweis bzw Abhängigkeit!
-
Ahh... Du hast ja eine .NET-COM... da geht dieses Vorgehen natürlich nicht mit dem WinForms-C#-Projekt... sorry... hatte ich übersehen...
Wenn Du mir die COM-DLL mal zumailst, mach ich Dir ein Beispiel...
-
Die korrekte Vorgehensweise ist:
C#-DLL erstellen und dann auf der Kommandozeile Folgendes eingeben:regasm QuoteSource.dll /codebase /tlb:QuoteSource.tlb
regasm QuoteSource.dll /codebase /tlb:QuoteSource.tlb /unregister
mt -managedassemblyname:QuoteSource.dll -nodependency -out:QuoteSource.manifestIm C++-Code Folgende Zeile einfügen:
#import "QuoteSource.tlb" no_namespace, raw_interfaces_only
Dem C++-Projekt eine Datei mit dem Namen "Appname.manifest" hinzufügen mit Folgedem Inhalt:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity name="QuoteSource" version="1.0.0.0" processorArchitecture="msil"></assemblyIdentity> </dependentAssembly> </dependency> </assembly>
Hier muss man nur sicherstellen, dass die Zeile mit dem "QuoteSource" dem Eintrag aus der "QuoteSource.manifest" Datei entspricht.
Fertig.
-
Hallo Jochen,
vielen dank für deine Hilfe.
dein Beispiel hat bei mir nicht gleich funktioniert. es wurde eine Abhängigkeit nicht gefunden. ich glaube, dass es an Microsoft.VC90.DebugCRT liegt weil ich auf meinen Rechner vs 2010 habe.
ich habe die COM- DLL und CPPTest in visual vs 2010 neu erstellt und die zeile<!--<dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC90.DebugCRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency>-->
in der CPPTest.manifest auskommeniert. es funktioniert!
ich habe bis jetzt noch nicht verstanden warum es bei mir am Anfang nicht funktioniert hat. was hast du anderes gemacht in deinem beispiel?
brauche ich so eine Abhängigkeit von vs 2010 c runtime in manifest file.
wenn ja . wo kriege ich diese infos raus
bi mir habe ich dieses info gefunden aber es fehlr mir noch die publicKeyTokentype="win32" name="Microsoft.VC100.DebugCRT" version="10.00.30313.1" processorArchitecture="x86" publicKeyToken="?">
ist es möglich den client-manifest nicht in der exe einzubetten, sondern als extern verwenden und den com-dll-manifest in der dll einbetten?
ich werde es ausprobieren
-
brauche ich so eine Abhängigkeit von vs 2010 c runtime in manifest file.
Nein. Ab VS2010 gibt es da nicht mehr....
-
[quote]ist es möglich den client-manifest nicht in der exe einzubetten, sondern als extern verwenden und den com-dll-manifest in der dll einbetten?
ich werde es ausprobieren [/qoute]
In der exe kannst Du es als externen Manifest machen. In die DLL kannst Du es nicht einbinden.
-
ich habe es hinbekommen mit einem manifest innerhalb der dll.
hier ist meine vorgehensweise
habe eine Anwendungsmanifestdatei zum DLL-projekt hinzugefügt und angepasst
app.manifest<?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assemblyIdentity name="QuoteSource" version="1.0.0.0" processorArchitecture="msil"> </assemblyIdentity> <clrClass clsid="{FCBE172E-4F13-4b88-8C94-6F74AB7FE14B}" progid="QuoteSource.QuoteProvider" threadingModel="Both" name="QuoteSource.QuoteProvider" runtimeVersion=""> </clrClass> <file name="QuoteSource.dll" hashalg="SHA1"> </file> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC-Manifestoptionen Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den requestedExecutionLevel-Knoten durch eines der folgenden Elemente. <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert. Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts- kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten. --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist. Windows wählt automatisch die am stärksten kompatible Umgebung aus.--> <!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.--> <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>--> </application> </compatibility> <!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren --> <!-- <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency>--> </asmv1:assembly>
aber ich habe gesehen dass .NET 2.0 als Zielframework eingestellt ist. wenn ich auf 4.0 umstelle und neu kompiliere und den client starte kommt ein Microsoft visual c++ Debug library fenster mit debug error