Pregunta ¿Cómo se puede combinar una ventana de C ++ en un exe de aplicación C #?


Tengo un programa de Windows C # que usa un dll de C ++ para datos de E / S. Mi objetivo es implementar la aplicación como un único EXE.

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


32
2017-09-16 13:38


origen


Respuestas:


Despliegue de ensamblaje único de código administrado y no administrado Domingo, 4 de febrero de 2007

Los desarrolladores de .NET adoran la implementación de XCOPY. Y aman los componentes de ensamblaje individuales. Al menos, siempre me siento un poco incómodo, si tengo que usar algún componente y necesito recordar una lista de archivos para incluir también con el ensamblaje principal de ese componente. Así que cuando recientemente tuve que desarrollar un componente de código administrado y tuve que aumentarlo con algún código no administrado de una DLL de C (gracias a Marcus Heege por ayudarme con esto), pensé en cómo facilitar el despliegue de las dos DLL . Si esto fuera solo dos ensamblajes, podría haber usado ILmerge para empacarlos en un solo archivo. Pero esto no funciona para los componentes de código mixto con DLL administrados y no administrados.

Así que esto es lo que se me ocurrió para una solución:

Incluyo las DLL que quiero implementar con el ensamblaje principal de mi componente como recursos integrados. Luego configuré un constructor de clase para extraer esas DLL como a continuación. El ctor de clase se llama solo una vez dentro de cada dominio de aplicación, así que es una sobrecarga insignificante, 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, incluí dos archivos DLL como recursos, uno de los cuales es un código DLL no administrado, y otro es un DLL de código administrado (solo para fines de demostración), para mostrar cómo funciona esta técnica para ambos tipos de código.

El código para extraer los archivos DLL en sus propios archivos 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 ensamblaje de código administrado como este es el mismo de siempre, casi. Usted lo referencia (aquí: ManagedService.dll) en el proyecto principal de su componente (aquí: MyLib), pero establece la propiedad Copy Local en false. Además, se vincula en el conjunto como un elemento existente y establece la acción de compilación en el recurso incrustado.

Para el código no administrado (aquí: UnmanagedService.dll), simplemente establece un enlace en la DLL como un elemento existente y establece la acción de compilación en el recurso incrustado. Para acceder a sus funciones, use el atributo DllImport como de costumbre, p.

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

¡Eso es! Tan pronto como cree la primera instancia de la clase con el ctor estático, las DLL incorporadas se extraen en sus propios archivos y están listas para usar como si las hubiera desplegado como archivos separados. Siempre que tenga permisos de escritura para el directorio de ejecución, esto debería funcionar bien para usted. Al menos para el código prototípico, creo que esta forma de implementación de ensamblaje único es bastante conveniente.

¡Disfrutar!

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


14
2017-09-16 13:40



Tratar boxedapp; permite cargar todas las DLL desde la memoria. Además, parece que incluso puedes incrustar el tiempo de ejecución .net. Bueno para crear aplicaciones realmente independientes ...


3
2017-09-25 19:55



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

ILMerge es una utilidad que se puede usar para fusionar múltiples ensamblados .NET en un solo ensamblaje. Está disponible de forma gratuita para su uso desde la página Herramientas y utilidades en Microsoft .NET Framework Developer Center.

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

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

Sin embargo, no funcionará con una DLL de Windows ordinaria (nativa).


1
2017-09-16 13:44



Simplemente haga clic con el botón derecho en su proyecto en Visual Studio, elija Propiedades del proyecto -> Recursos -> Agregar recurso -> Agregar archivo existente ... E incluya el código a continuación en su App.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 entrada de blog original: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/


1
2018-06-15 18:25



Utilizar Fody.Costura nuget

  1. Abra su solución -> Proyecto -> Administrar paquetes de Nuget
  2. Buscar Fody.Costura
  3. Compilar tu proyecto.

Eso es !

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


1
2018-06-30 20:32



Thinstall es una solución. Para una aplicación de Windows nativa sugeriría incrustar la DLL como un objeto de recurso binario, y luego extraerlo en tiempo de ejecución antes de que lo necesite.


0
2017-09-16 13:40



Asamblea inteligente puede hacer esto y más. Si su dll tiene un código no administrado, no le permitirá fusionar los dlls en un único ensamblado, sino que puede incorporar las dependencias requeridas como recursos a su exe principal. Es flip-side, no es gratis.

Puede hacerlo manualmente insertando dll en sus recursos y luego confiando en el ensamblado de AppDomain ResolveHandler. Cuando se trata de dlls de modo mixto, encontré muchas de las variantes y sabores de ResolveHandler enfoque para que no funcione para mí (todos los cuales leen dll bytes a la memoria y leen de ella). Todos trabajaron para dlls gestionados. Esto 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 cargar desde su ubicación. Para evitar el problema del huevo y la gallina, debe asegurarse de declarar el controlador antes de acceder al ensamblaje y de no acceder a los miembros del ensamblaje (o crear una instancia de todo lo que tenga que ver con el ensamblaje) dentro de la pieza de carga (resolución de ensamblaje). También tenga cuidado de asegurar GetMyApplicationSpecificPath() no es un directorio temporal, ya que los archivos temporales pueden ser borrados por otros programas o por usted mismo (no es que se eliminen mientras su programa está accediendo al dll, pero al menos es una molestia. AppData es una buena ubicación). También tenga en cuenta que debe escribir los bytes cada vez, no puede cargar desde la ubicación solo porque el dll ya reside allí.

Si el ensamblaje no está completamente administrado, puede ver esto enlazar o esta en cuanto a cómo cargar tales dlls.


0
2018-05-15 11:42



PostBuild desde Xenocode puede empaquetar administrado y no gestionado en un solo exe.


-2
2018-04-10 19:58