【问题标题】:Incorporate an unmanaged EXE as resource in a managed C# code将非托管 EXE 作为资源合并到托管 C# 代码中
【发布时间】:2012-03-05 16:43:36
【问题描述】:

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

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

我怎样才能做到这一点?

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

而且我不想有两个单独的 EXE 文件。有什么想法吗?


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

【问题讨论】:

  • 你想用这个非托管的可执行文件做什么?运行?您必须保存嵌入式 EXE,可能保存到 %TEMP% 路径,并使用 Process.Start 来启动它。然后使用WaitForExit,并删除EXE进行清理。
  • 这确实是个好主意,但我宁愿在不生成嵌入式 EXE 的情况下完成这项工作
  • 您应该能够使用 C++/CLI 编译器将 C++ 编译为混合模式程序集,并将其与您的 C# 代码链接到单个文件中。

标签: c# c++ .net unmanaged


【解决方案1】:

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

【讨论】:

  • 好的,但也许有人可以给我一个提示,让我在没有 Assembly.Load 的情况下完成这项工作
  • @GianT971 我想你在尝试打包单个 exe 之前已经尝试过游戏。按照 Alexei (+1) 的建议遵循一些 PInvoke 教程
  • 看看这个,明天给反馈
【解决方案2】:

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

【讨论】:

  • “在运行时将资源保存到磁盘”是什么意思?我该怎么做?*
  • 好的,您认为这样的结果可能与仅将 dll 导入项目不同?
  • 不确定“不同”是什么意思 - 您不能将本机 DLL“导入”到托管项目。
  • @AlexeiLevenkov 正如 Ramhound 所发现的,可以使用 dllimport,这就是我正在做的,因此“不同”
【解决方案3】:

可以自动化的稍微不同的方法是使用所谓的“组装编织” Costura.Fody - https://github.com/Fody/Costura - 是“织布工”之一。嵌入过程(带有测试自动化)用于合并非托管资源并在运行时透明地加载它们而无需太多努力 -

Install-Package Fody.Costura

然后默认情况下,所有嵌入、解包、程序集定位和加载都是自动化的,并通过添加到您的项目中的“FodyWeavers.xml”配置来控制。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2013-02-02
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多