生成一个 CIL 可执行文件而不是 EXE 然后执行它

Dav*_*nka 3 .net c# cil

我有生成 EXE 文件的 ac# 项目。现在,我处于“安全”的公司环境中,我可以在其中编译我的项目,但无法执行 EXE 文件。

作为Java程序员,我想知道是否没有办法将c#项目编译成不是EXE文件而是CIL文件的东西,然后通过对应于java.exe的东西执行CIL文件网络世界。

编辑以回应评论:

  1. 我可以运行由包管理器安装的 exe 文件
  2. 是的,我知道公司政策很愚蠢。

Lua*_*aan 5

嗯,这应该很容易。

.NET 可执行文件和其他任何文件一样只是 DLL - 主要区别在于可执行文件格式本身,以及 EXE 文件有一个入口点,而 DLL 没有。

这也意味着您可以像使用 DLL 一样将 EXE 加载到内存中:

Assembly.LoadFrom("SomeExe.exe");
Run Code Online (Sandbox Code Playgroud)

您已经完成了一半 - 现在我们只需要找到并执行入口点。不出所料,这很简单:

var assembly = Assembly.LoadFrom("SomeExe.exe");
assembly.EntryPoint.Invoke(null, null);
Run Code Online (Sandbox Code Playgroud)

对于大多数应用程序,这应该可以正常工作;对于某些情况,您必须确保用于调用入口点的线程分别具有STAThreadMTAThreadThread.TrySetThreadApartment如果您正在启动一个新线程)。

它可能需要针对某些应用程序进行调整,但修复起来应该不会太难。

因此,您可以制作一些仅真正包含这两行代码的引导程序(“解释器”)。如果您甚至无法获得批准,并且您确实需要某种作为“官方包”的东西,请尝试一些允许您执行任意代码的 .NET 应用程序 - 例如,LINQPad 或 PowerShell。

编辑:

当然,这确实有局限性,并且确实引入了一些额外的设置工作:

  • 引导程序必须以相同或更高版本的 .NET Framework 为目标。.NET Portable 可能特别棘手,但我认为您已经很好地控制了这一点。它还必须具有相同的位数(如果明确指定)。
  • 您需要通过引导程序运行调试。这实际上并不太难 - 只需转到项目属性,调试并选择“启动外部程序”。
  • 引导程序必须在完全信任的条件下运行——这是反射工作所必需的。在大多数系统上,这仅意味着您必须将 exe 作为本地文件(例如,不是来自网络共享)。默认情况下,像 LINQPad 这样的工具将在完全信任的情况下运行。
  • 应用程序不得依赖于Assembly.GetEntryAssembly. 这不是经常使用的,所以它应该不是问题。很多类似的问题也应该没问题,因为您构建了要自己运行的应用程序。

  • 哪个可执行文件将运行`Assembly.Load("SomeExe.exe")`?OP 无法在其环境中运行任意可执行文件。你将如何调试`SomeExe.exe`?你将如何从 Visual Studio 启动它? (2认同)
  • 谢谢大家。我现在就试试这个。供您参考,我也已开始正式流程以消除障碍。 (2认同)