C# .dll 程序集可以包含入口点吗?
Posted
技术标签:
【中文标题】C# .dll 程序集可以包含入口点吗?【英文标题】:Can a C# .dll assembly contain an entry point? 【发布时间】:2012-03-23 13:40:00 【问题描述】:我的目标是创建一个可执行文件来启动影子复制应用程序。诀窍是,我希望这个启动程序没有外部依赖项,并且不必包含有关它必须启动的程序的任何知识。
我还希望它成为目录中唯一的可执行文件。换句话说,我希望它“运行”一个 .dll 程序集而不是一个 .exe 程序集。 (我可以要求加载到新 AppDomain 中的 .dll 文件的名称每次都相同,例如 Main.dll 或类似的名称。)
看起来AppDomain.ExecuteAssembly 会做我想做的事。它说它将在“.NET Framework 标头中指定的入口点”开始执行。
当我尝试使用该函数时,我收到错误“在程序集 'DllApp' 中找不到入口点”。
我有的启动程序,只是想运行程序集:
static void Main()
AppDomain domain = AppDomain.CreateDomain( "DllApp" );
domain.ExecuteAssembly( "DllApp.dll" );
.dll 文件中的应用程序代码,具有默认入口点:
static class Program
[STAThread]
static void Main()
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault( false );
Application.Run( new Form1() );
This page on Main() functions 说“库和服务不需要 Main 方法作为入口点”。它也没有说他们不能有默认入口点。
我已经尝试了 public/private static void main、int 返回类型、string[] args 作为参数、有命名空间、没有命名空间、静态/非静态类等的所有各种排列。
我能够将我的代码更改为从 MarshalByRefObject 继承,然后使用 CreateInstance 创建一个对象,但这似乎会使启动器与它应该启动的程序更紧密地耦合。如果我可以使用 ExecuteAssembly,正在启动的应用程序只需要一个静态 void Main,这真的很简单,也很难搞砸。
.dll 程序集是否有可能有一个默认入口点,并且 ExecuteAssembly 可以找到它,还是我只需要辞职走另一条路?
【问题讨论】:
拥有 .NET 程序集 (dll) 的入口点是没有意义的,因为它本身不会作为进程启动。 【参考方案1】:您可以将 .NET 应用程序编译为 exe(它是一个程序集)并将其重命名为 .DLL,它将充当普通的 .NET .dll 程序集。然后它将拥有您的入口点。
【讨论】:
这工作完美,无需更改任何其他内容。想知道为什么我没想到...谢谢基思。【参考方案2】:简短的回答是否定的。 .DLL 文件是一个动态链接库,它是由另一个库调用的代码。我猜 Keith 所说的在技术上是可行的.. 只要您以正确的方式启动应用程序,您甚至可以将其重命名为您想要的任何内容,甚至是 .txt 或 .pdf。我的主要问题是这个;你想做什么??除非您尝试编写恶意软件,否则为什么要这样做? 并不是说我宽恕出于恶意目的编写恶意软件,但我知道人们喜欢在自己的实验室中进行实验,所以我不谴责它。如果你正在编写恶意软件,比如 c++,c 或汇编程序可能是更好的选择,我猜 C# 可以完成这项工作,但是嗯……
【讨论】:
我的回答是编译器生成 dll 或 exe,但两者都是程序集,它只是 exe 是定义了入口点的程序集,这就是他所要求的。 不,这里没有恶意软件。我正在尝试创建一个小型启动程序来影子复制我的主应用程序。然后我可以轻松地更新我的主应用程序,而无需跳过其他单独的可执行文件进行更新等。我只是希望启动器在可能的情况下完全解耦,然后我可以将它与我的所有应用程序一起使用。 “除非你试图编写恶意软件” LOL!! “普通”win32 dll 具有入口点,可在进程附加到库时初始化库,或在所有进程已卸载时完成。这是正常的做法,因此对恶意软件的指控是不正常的。【参考方案3】:我发现这些建议并不容易遵循。经过一些实验,这就是我成功的方式:
我用一个简单的 main 创建了一个控制台应用程序,并包含了我原始 DLL 中的其余代码。下面是一个包含 DLL 的简化程序:
namespace FIT.DLLTest
public class DLLTest
[STAThread]
static void Main(string[] args)
int a = 1;
public DLLTest()
int b = 17;
public int Add(int int1, int int2)
return int1 + int2;
编译后我将生成的 .exe 重命名为 .DLL。
在使用 DLL 的母程序中,我首先添加了 DLLTest.dll 作为引用,然后添加了执行 DLL 的代码。
namespace TestDLLTest
class TestDLLTest
static void Main(string[] args)
AppDomain domain = AppDomain.CreateDomain( "DLLTest" );
domain.ExecuteAssembly( "DllTest.dll" );
DLLTest dt = new DLLTest();
int res2 = dt.Add(6, 8);
int a = 1;
Violà 我可以在 DLLTest.Main 方法中执行并添加一个断点,然后看到我可以调用 DLLTest 的 Main。谢谢大家的讨论!
【讨论】:
以上是关于C# .dll 程序集可以包含入口点吗?的主要内容,如果未能解决你的问题,请参考以下文章