如何将C ++ Windows dll合并到C#应用程序exe中?

时间:2020-03-05 18:55:57  来源:igfitidea点击:

我有一个Windows C程序,它使用C ++ dll进行数据I / O。我的目标是将应用程序部署为单个EXE。

创建此类可执行文件的步骤是什么?

解决方案

回答

托管和非托管代码的单一程序集部署
2007年2月4日,星期日

.NET开发人员喜欢XCOPY部署。而且他们喜欢单一装配部件。如果我必须使用某些组件并且需要记住该组件的主程序集中也包含的文件列表,至少我总会感到不安。因此,当我最近不得不开发托管代码组件,并用来自C DLL的一些非托管代码对其进行扩充时(向Marcus Heege表示感谢,以帮助我解决这个问题!),我想到了如何简化两个DLL的部署。 。如果这只是两个程序集,我本可以使用ILmerge将它们打包在一个文件中。但这对于具有托管和非托管DLL的混合代码组件不起作用。

因此,我想出了一个解决方案:

我将要与组件主装配一起部署的所有DLL都包含在内,作为嵌入式资源。
然后,我设置了一个类构造函数以提取这些DLL,如下所示。我认为,类ctor在每个AppDomain中仅被调用一次,因此其开销可忽略。

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

        ...

在此示例中,我包括了两个DLL作为资源,一个是非托管代码DLL,一个是托管代码DLL(仅用于演示目的),以说明该技术如何在两种代码中起作用。

将DLL提取到自己的文件中的代码很简单:

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

像这样使用托管代码程序集几乎和通常一样。我们在组件主项目(此处为MyLib)中引用它(此处为ManagedService.dll),但是将"复制本地"属性设置为false。此外,我们可以将装配体链接为现有项,并将"生成操作"设置为"嵌入式资源"。

对于非托管代码(此处为:UnmanagedService.dll),我们只需将DLL作为现有项进行链接,并将"生成操作"设置为"嵌入式资源"。要访问其功能,请照常使用DllImport属性,例如

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

而已!一旦使用静态ctor创建该类的第一个实例,嵌入式DLL就会被提取到它们自己的文件中,并且可以像将它们作为单独文件部署一样使用。只要我们对执行目录具有写权限,这对我们来说就可以正常工作。至少对于原型代码,我认为这种单程序集部署方式非常方便。

享受!

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

回答

Thinstall是一种解决方案。对于本机Windows应用程序,我建议将DLL嵌入为二进制资源对象,然后在需要时在运行时将其提取。

回答

我们是否尝试过ILMerge? http://research.microsoft.com/~mbarnett/ILMerge.aspx

ILMerge is a utility that can be used to merge multiple .NET assemblies into a single assembly. It is freely available for use from the Tools & Utilities page at the  Microsoft .NET Framework Developer Center.

如果我们要使用/ clr标志(全部或者部分C ++ / CLI)构建C ++ DLL,那么它应该可以工作:

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

但是,它不适用于普通的(本机)Windows DLL。

回答

尝试boxedapp;它允许从内存加载所有DLL。另外,似乎我们甚至可以嵌入.net运行时。创建一个真正独立的应用程序是一件好事...

回答

Xenocode的PostBuild可以将托管和非托管打包到一个exe中。