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

Generate a CIL executable not EXE then execute it

我有一个生成 EXE 文件的 c# 项目。现在,我在"secure"企业环境中,我可以编译我的项目,但我不能执行EXE文件。

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

编辑以回应评论:

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

嗯,这应该很简单。

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

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

Assembly.LoadFrom("SomeExe.exe");

您已经完成了一半 - 现在我们只需要找到并执行入口点。毫不奇怪,这 非常微不足道:

var assembly = Assembly.LoadFrom("SomeExe.exe");
assembly.EntryPoint.Invoke(null, null);

对于大多数应用程序,这应该工作得很好;对于某些人,您必须确保用于调用入口点的线程分别具有 STAThreadMTAThread(如果您正在启动一个新线程,则为 Thread.TrySetThreadApartment)。

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

所以你可以做一些只真正包含这两行代码的bootstrap应用程序("interpreter")。如果您连那个都得不到批准,并且您确实需要 "official package" 之类的东西,请尝试一些允许您执行任意代码的 .NET 应用程序 - 例如,LINQPad 或 PowerShell。

编辑:

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

  • bootstrapper 必须针对相同或更高版本的 .NET Framework。 .NET Portable 可能特别棘手,但我假设您已经很好地控制了它。它还必须具有相同的位数(如果明确指定)。
  • 您需要 运行 通过 bootstrapper 进行调试。这实际上并不太难 - 只需转到项目属性,调试和 select "Start external program".
  • bootstrapper 必须 运行 在完全信任的条件下 - 反思工作是必要的。在大多数系统上,这仅仅意味着您必须将 exe 作为本地文件(例如,不是来自网络共享)。默认情况下,LINQPad 等工具 运行 处于完全信任状态。
  • 应用程序不得依赖于 Assembly.GetEntryAssembly。这不是经常使用,所以它应该不是问题。相当多的类似问题也应该没问题,因为您自己构建了您尝试 运行 的应用程序。