将非托管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
无法按预期工作。现在就要结束帖子了,感谢所有回复的人。
您不能用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等。