将非托管EXE作为资源合并到托管C#代码中

本文关键字:代码 合并 EXE 资源 | 更新日期: 2023-09-27 18:27:00

我有一个用非托管C++编写的给定代码,我将其作为资源添加到C#程序中。

当尝试使用Assembly.Load加载非托管EXE时,我得到了一个BadImageFormatException,其InnerException表示"IL格式不正确"(显然)。

我怎样才能做到这一点?

我知道将代码用作DLL会更好,但由于某些原因,DLL调用的行为与使用System.Diagnostics.Process.Start运行非托管exe时不同。

我不想有两个单独的EXE文件。知道吗?


编辑:好的,我不再需要这么做了。我的dll的行为方式不同,因为我在不同的上下文中使用它(winform而不是控制台);因此,导致问题的函数SetThreadDesktop无法按预期工作。现在就要结束帖子了,感谢所有回复的人。

将非托管EXE作为资源合并到托管C#代码中

您不能用Assembly.Load()加载非托管的exe/dll,它只能与托管的一起工作。如果您需要在该非托管文件上PInvoke,而您想要单个exe的原因只是部署,则可以将其打包为嵌入式资源(如当前所做的那样),并在目标计算机上解压缩为一个文件,然后照常使用。

如果您有非托管DLL作为资源-基本步骤:

  • 在运行时将资源保存到磁盘
  • 使用LoadLibrary(使用PInvoke对LoadLibrary的Win32调用)
  • 可以通过调用为PInvoke注释的方法来使用此库中的方法,也可以通过GetProcAddress手动使用

略有不同的方法是使用所谓的"组装编织"Costura Fodyhttps://github.com/Fody/Costura-是"编织者"之一。嵌入过程(具有测试自动化),用于合并非托管资源并在运行时透明地加载它们,而无需付出太多努力-

Install-Package Fody.Costura

然后,默认情况下,所有的嵌入、拆包、组件定位和加载都是自动的,并通过将"FodyWeavers.xml"配置添加到您的项目中进行控制。

<Costura> <Unmanaged32Assemblies> Foo32 Bar32 </Unmanaged32Assemblies> <Unmanaged64Assemblies> Foo64 Bar64 </Unmanaged64Assemblies> </Costura>

方法背后的概念是静态<Module>类加载器,它是在成功构建项目程序集后由Fody项目任务更改的二进制文件。在内部Mono.Cecil用于静态'<Module>'加载程序注入,该加载程序自动打开资源的包装,将其保存到临时目录,并在程序集加载事件中告知从该位置加载dll等。