简体   繁体   English

使用exe编译非托管DLL

[英]Compiling unmanaged DLLs with exe

I am trying to embed a bunch of DLLs in my C# executable using costura fody, but I am having some trouble with 2 DLLs. 我正在尝试使用costura fody将一堆DLL嵌入我的C#可执行文件中,但是我在使用2个DLL时遇到了一些麻烦。 I am using the NAudio library and the NAudio.Lame library, and while both DLLs compile perfectly into the exe, the NAudio.Lame package adds the dlls "libmp3lame.64.dll" and "libmp3lame.32.dll", which I am not able to compile with the exe. 我正在使用NAudio库和NAudio.Lame库,虽然两个DLL都可以完美地编译到exe中,但NAudio.Lame包中添加了dlls“ libmp3lame.64.dll”和“ libmp3lame.32.dll”。无法使用exe进行编译。 I have tried adding the following in the FodyWeavers.xml file under the Costura node: 我尝试在Costura节点下的FodyWeavers.xml文件中添加以下内容:

<Unmanaged32Assemblies>
    libmp3lame.32
</Unmanaged32Assemblies>
<Unmanaged64Assemblies>
    libmp3lame.64
</Unmanaged64Assemblies>

The XML does not change the filesize of the exe, so I assume it did nothing. XML不会更改exe的文件大小,因此我认为它没有执行任何操作。

I have also tried to change the "Build Action" of the DLLs to "Embedded Resource", and while the executable file size increases significantly, I get a Runtime DLLNotFoundExeption if I launch the program without the DLLs in the same folder as the exe. 我还尝试将DLL的“生成操作”更改为“嵌入式资源”,并且尽管可执行文件的大小显着增加,但是如果我在没有与exe相同的文件夹中启动DLL的情况下启动程序,则会得到运行时DLLNotFoundExeption。

EDIT: I now noticed that I only need the 64 bit dll for the program to run on my computer, but I am not able to add only that dll either 编辑:我现在注意到,我只需要64位dll即可在我的计算机上运行该程序,但是我无法仅添加该dll

EDIT2: I tried setting up an event for AssemblyResolve using the following code: EDIT2:我尝试使用以下代码为AssemblyResolve设置事件:

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Client.libmp3lame.64.dll")) {
            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return Assembly.Load(assemblyData);
        }
    }

It left a System.BadImageFormatException this time, as I think this code only works for managed DLLs. 这次它留下了System.BadImageFormatException,因为我认为这段代码仅适用于托管DLL。

I found a solution! 我找到了解决方案!

Apparently all I needed to do was to create the folders Costura32 and Costura64 in the root of my project, put the 32-bit and 64-bit DLLs in their respective folders, change their build action to "Embedded Resource" and compile with my original Costura settings. 显然,我要做的就是在项目的根目录中创建Costura32和Costura64文件夹,将32位和64位DLL放入各自的文件夹中,将其生成操作更改为“嵌入式资源”,然后使用我的原始文件进行编译Costura设置。

This is how my project looks: 这是我的项目的外观:

解决方案资源管理器的屏幕截图

This is my FodyWeavers.xml: 这是我的FodyWeavers.xml:

<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  <Costura>
    <IncludeAssemblies>
        NAudio
        NAudio.Lame
    </IncludeAssemblies>
    <Unmanaged32Assemblies>
      libmp3lame.32
    </Unmanaged32Assemblies>
    <Unmanaged64Assemblies>
      libmp3lame.64
    </Unmanaged64Assemblies>  
  </Costura>
</Weavers>

Add the file to your project as "Embedded resource": 将文件作为“嵌入式资源”添加到您的项目中:

嵌入式资源

Save then to the main assembly directory: 然后保存到主装配目录:

Assembly assembly = this.GetType().Assembly;
string assemblyLocation = System.IO.Path.GetDirectoryName(assembly.Location);

if (!System.IO.File.Exists(System.IO.Path.Combine(assemblyLocation, "libmp3lame.64.dll")))
{
    using (FileStream fileStream = new FileStream(assemblyLocation + "libmp3lame.64.dll", FileMode.CreateNew, FileAccess.Write, FileShare.None))
        assembly.GetManifestResourceStream("Client.libmp3lame.64.dll").CopyTo(fileStream);
}

COM dll cannot be loaded to the domain, you need to save it on application root only. 无法将COM dll加载到域,您只需要将其保存在应用程序根目录下即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM