Embedding DLLs in a compiled executable

前端 未结 16 2674
情深已故
情深已故 2020-11-21 07:07

Is it possible to embed a pre-existing DLL into a compiled C# executable (so that you only have one file to distribute)? If it is possible, how would one go about doing it?<

16条回答
  •  臣服心动
    2020-11-21 07:46

    I use the csc.exe compiler called from a .vbs script.

    In your xyz.cs script, add the following lines after the directives (my example is for the Renci SSH):

    using System;
    using Renci;//FOR THE SSH
    using System.Net;//FOR THE ADDRESS TRANSLATION
    using System.Reflection;//FOR THE Assembly
    
    //+ref>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
    //+res>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
    //+ico>"C:\Program Files (x86)\Microsoft CAPICOM 2.1.0.2 SDK\Samples\c_sharp\xmldsig\resources\Traffic.ico"
    

    The ref, res and ico tags will be picked up by the .vbs script below to form the csc command.

    Then add the assembly resolver caller in the Main:

    public static void Main(string[] args)
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        .
    

    ...and add the resolver itself somewhere in the class:

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            String resourceName = new AssemblyName(args.Name).Name + ".dll";
    
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            {
                Byte[] assemblyData = new Byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return Assembly.Load(assemblyData);
            }
    
        }
    

    I name the vbs script to match the .cs filename (e.g. ssh.vbs looks for ssh.cs); this makes running the script numerous times a lot easier, but if you aren't an idiot like me then a generic script could pick up the target .cs file from a drag-and-drop:

        Dim name_,oShell,fso
        Set oShell = CreateObject("Shell.Application")
        Set fso = CreateObject("Scripting.fileSystemObject")
    
        'TAKE THE VBS SCRIPT NAME AS THE TARGET FILE NAME
        '################################################
        name_ = Split(wscript.ScriptName, ".")(0)
    
        'GET THE EXTERNAL DLL's AND ICON NAMES FROM THE .CS FILE
        '#######################################################
        Const OPEN_FILE_FOR_READING = 1
        Set objInputFile = fso.OpenTextFile(name_ & ".cs", 1)
    
        'READ EVERYTHING INTO AN ARRAY
        '#############################
        inputData = Split(objInputFile.ReadAll, vbNewline)
    
        For each strData In inputData
    
            if left(strData,7)="//+ref>" then 
                csc_references = csc_references & " /reference:" &         trim(replace(strData,"//+ref>","")) & " "
            end if
    
            if left(strData,7)="//+res>" then 
                csc_resources = csc_resources & " /resource:" & trim(replace(strData,"//+res>","")) & " "
            end if
    
            if left(strData,7)="//+ico>" then 
                csc_icon = " /win32icon:" & trim(replace(strData,"//+ico>","")) & " "
            end if
        Next
    
        objInputFile.Close
    
    
        'COMPILE THE FILE
        '################
        oShell.ShellExecute "c:\windows\microsoft.net\framework\v3.5\csc.exe", "/warn:1 /target:exe " & csc_references & csc_resources & csc_icon & " " & name_ & ".cs", "", "runas", 2
    
    
        WScript.Quit(0)
    

提交回复
热议问题