41 Stimmen

Wie kann eine C++-Windows-DLL in eine C#-Anwendungs-Exe eingebunden werden?

Ich habe ein Windows-C#-Programm, das eine C++-DLL für Daten-E/A verwendet. Mein Ziel ist es, die Anwendung als eine einzige EXE bereitzustellen.

Was sind die Schritte zur Erstellung einer solchen ausführbaren Datei?

0voto

titanae Punkte 2269

Thinstall ist eine Lösung. Für eine native Windows-Anwendung würde ich vorschlagen, die DLL als binäres Ressourcenobjekt einzubetten und sie dann zur Laufzeit zu extrahieren, bevor Sie sie benötigen.

0voto

nawfal Punkte 65966

Intelligente Montage kann dies und mehr tun. Wenn Ihre DLL nicht verwalteten Code hat, können Sie die DLLs nicht zu einer einzigen Assembly zusammenführen, sondern die erforderlichen Abhängigkeiten als Ressourcen in Ihre Haupt-Exe einbetten. Die Kehrseite der Medaille ist, dass es nicht kostenlos ist.

Sie können dies manuell tun, indem Sie die DLL in Ihre Ressourcen einbetten und sich dann auf die AppDomain Assembly verlassen ResolveHandler . Bei den Mixed-Mode-DLLs fand ich viele der Varianten und Geschmacksrichtungen von ResolveHandler Ansatz für mich nicht funktionieren (alle, die dll Bytes in den Speicher zu lesen und aus ihm zu lesen). Sie alle funktionierten für verwaltete dlls. Hier ist, was für mich gearbeitet:

static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        string assemblyName = new AssemblyName(args.Name).Name;
        if (assemblyName.EndsWith(".resources"))
            return null;

        string dllName = assemblyName + ".dll";
        string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);

        using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
        {
            byte[] data = new byte[stream.Length];
            s.Read(data, 0, data.Length);

            //or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);

            File.WriteAllBytes(dllFullPath, data);
        }

        return Assembly.LoadFrom(dllFullPath);
    };
}

Der Schlüssel dazu ist, die Bytes in eine Datei zu schreiben und von dort zu laden. Um das Henne-Ei-Problem zu vermeiden, müssen Sie sicherstellen, dass Sie den Handler vor dem Zugriff auf die Baugruppe deklarieren und dass Sie nicht auf die Baugruppenmitglieder zugreifen (oder irgendetwas instanziieren, das mit der Baugruppe zu tun hat) innerhalb des ladenden (Baugruppen auflösenden) Teils. Achten Sie auch darauf, dass GetMyApplicationSpecificPath() ist kein temporäres Verzeichnis, da temporäre Dateien von anderen Programmen oder von Ihnen selbst gelöscht werden könnten (nicht, dass sie gelöscht werden, während Ihr Programm auf die dll zugreift, aber es ist zumindest ein Ärgernis). AppData ist ein guter Ort). Beachten Sie auch, dass Sie die Bytes jedes Mal neu schreiben müssen, Sie können nicht von einem Ort laden, nur weil die Dll dort bereits vorhanden ist.

Wenn die Baugruppe vollständig unverwaltet ist, sehen Sie dies Link oder diese wie man solche DLLs lädt.

-2voto

Joel Lucsy Punkte 8402

PostBuild von Xenocode kann sowohl verwaltete als auch unveränderte Dateien in einer einzigen Exe-Datei zusammenfassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X