¿Cómo puede un C++ dll de windows fusionarán en una aplicación de C# exe?

StackOverflow https://stackoverflow.com/questions/72264

  •  09-06-2019
  •  | 
  •  

Pregunta

Tengo un Windows C# programa que utiliza una dll de C++ para e/s de datos.Mi objetivo es desplegar la aplicación como un único archivo EXE.

¿Cuáles son los pasos para crear un ejecutable?

¿Fue útil?

Solución

Solo Asamblea de Implementación de Código administrado y no Administrado El Domingo, 4 De Febrero De 2007

.RED de desarrolladores de amor la implementación de XCOPY.Y que el amor solo componentes de la asamblea.Al menos siempre me siento un poco incómodo, si tengo que utilizar algún componente y la necesidad de recordar una lista de archivos para incluir también con los principales de la asamblea de ese componente.Así que cuando hace poco he tenido que desarrollar un código administrado componente y había enriquecerlo con código no administrado desde una DLL de C (thx a Marcus Heege por ayudarme con esto!), Pensé acerca de cómo hacer más fácil el despliegue de los dos archivos Dll.Si sólo se tratara de dos asambleas que podría haber utilizado ILmerge empacarlas en un solo archivo.Pero esto no funciona para el mezclado de los componentes de código gestionado, así como Dll no administradas.

Por lo que heres lo que se me ocurrió una solución:

Puedo incluir cualquier Dll quiero implementar con mis componentes principales de la asamblea como recursos incrustados.A continuación, he creado un constructor de la clase a fin de extraer los archivos Dll como en la figura siguiente.La clase cto r se llama sólo una vez dentro de cada dominio de aplicación, lo que es un imperceptible sobrecarga, creo.

namespace MyLib
{
    public class MyClass
    {
        static MyClass()
        {
            ResourceExtractor.ExtractResourceToFile("MyLib.ManagedService.dll", "managedservice.dll");
            ResourceExtractor.ExtractResourceToFile("MyLib.UnmanagedService.dll", "unmanagedservice.dll");
        }

        ...

En este ejemplo he incluido dos archivos Dll como recursos, siendo uno de ellos un código no administrado DLL, y uno de ellos un código administrado DLL (sólo para fines de demostración), para mostrar, cómo esta técnica funciona para ambos tipos de código.

El código para extraer los archivos Dll en los archivos de su propio es simple:

public static class ResourceExtractor
{
    public static void ExtractResourceToFile(string resourceName, string filename)
    {
        if (!System.IO.File.Exists(filename))
            using (System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
                {
                    byte[] b = new byte[s.Length];
                    s.Read(b, 0, b.Length);
                    fs.Write(b, 0, b.Length);
                }
    }
}

Trabajar con un ensamblado de código administrado como este es el mismo como de costumbre - casi.Usted referencia (aquí:ManagedService.dll) en los componentes principales del proyecto (aquí:MyLib), pero establece la Copia Local de la propiedad a false.Además, el vínculo en la asamblea, como un Elemento Existente y configurar la Acción de generación de Recursos Incrustados.

Para el código no administrado (aquí:UnmanagedService.dll) que acaba de enlace en el archivo DLL como un Elemento Existente y configurar la Acción de generación de Recursos Incrustados.Para acceder a sus funciones utilice el atributo DllImport como de costumbre, por ejemplo,

[DllImport("unmanagedservice.dll")] public extern static int Add(int a, int b);

Eso es todo!Tan pronto como se crea la primera instancia de la clase con la estática cto r de la incrustados Dll se vuelven a extraer en los archivos de su propia y están listos para usar, como si se implementa como archivos separados.Mientras usted tiene los permisos de escritura para el directorio de ejecución esto debería funcionar bien para usted.Al menos para el prototipo de código creo que esta forma de single de la asamblea de la implementación es muy conveniente.

¡A disfrutar!

http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx

Otros consejos

Trate de boxedapp;permite la carga de todos los archivos Dll de la memoria.También, parece que se puede incrustar .net runtime.Bueno para crear una realidad independiente de las aplicaciones...

Uso Fody.Costura nuget

  1. Abra su solución -> Proyecto -> Administrar Paquetes de Nuget
  2. Búsqueda de Fody.Costura
  3. Compilar su proyecto.

Eso es todo !

Fuente: http://www.manuelmeyer.net/2016/01/net-power-tip-10-merging-assemblies/

¿Has probado ILMerge? http://research.microsoft.com/~mbarnett/ILMerge.aspx

ILMerge es una utilidad que puede ser utilizado para combinar varias .NET ensamblados en una sola asamblea.Es de libre disposición para el uso de las Herramientas y Utilidades en la página de Microsoft .NET Framework Developer Center.

Si usted está construyendo la DLL en C++ con el /clr indicador (total o parcialmente C++/CLI), entonces debería funcionar:

ilmerge /out:Composite.exe MyMainApp.exe Utility.dll

No va a funcionar con una corriente (nativo) de Windows DLL sin embargo.

Simplemente haga clic derecho en el proyecto en Visual Studio, elija Propiedades del Proyecto -> Recursos -> Agregar Recursos -> Añadir Archivo Existente... E incluir el código de abajo en tu Aplicación.xaml.cs o equivalente.

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");

    dllName = dllName.Replace(".", "_");

    if (dllName.EndsWith("_resources")) return null;

    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());

    byte[] bytes = (byte[])rm.GetObject(dllName);

    return System.Reflection.Assembly.Load(bytes);
}

Aquí está mi blog original post:http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/

Thinstall es una solución.Para una aplicación nativa de windows sugeriría incrustar el archivo DLL como un recurso binario objeto, a continuación, extraer en tiempo de ejecución antes de que la necesite.

Smart Asamblea puede hacer esto y mucho más.Si su archivo dll tiene código no administrado, no lo puedo dejar de combinar los archivos dll de una sola asamblea, en su lugar se pueden incrustar las dependencias necesarias como recursos para su ejecutable principal.Su otra cara, que no es libre.

Usted puede hacer esto de forma manual mediante la incorporación de dll para sus recursos y, a continuación, confiando en el dominio de aplicación de la Asamblea ResolveHandler.Cuando se trata de modo mixto de dll, he encontrado muchas de las variantes y sabores de ResolveHandler enfoque no funciona para mí (todo el que lea dll bytes de memoria y leer de ella).Todos ellos trabajaron para manejo de archivos dll.Aquí es lo que funcionó para mí:

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);
    };
}

La clave aquí es escribir los bytes en un archivo y carga de su ubicación.Para evitar que el pollo y el huevo problema, usted tiene que asegurarse de que usted declare el controlador antes de acceder a la asamblea y que no tienen acceso a los miembros de la asamblea (o crear instancias de algo que tiene que lidiar con la "asamblea") en el interior de la carga (la resolución de la asamblea) parte.También tener cuidado para asegurarse de GetMyApplicationSpecificPath() no es cualquier directorio temp desde archivos temporales podría ser tratado de ser borrado por otros programas o por sí mismo (no es que vaya a quedar eliminados, mientras que su programa es el acceso a la dll, pero al menos es una molestia.AppData es una buena ubicación).También tenga en cuenta que usted tiene que escribir los bytes cada vez, usted no puede cargar de ubicación sólo porque la dll ya se encuentra allí.

Si la asamblea es totalmente no administrado, usted puede ver esto enlace o este cómo cargar archivos dll.

PostBuild de Xenocode puede empaquetar y administrado unmanged en un único archivo exe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top