C# .dll 程序集可以包含入口点吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9577567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a C# .dll assembly contain an entry point?
提问by Sean
My goal is to create an executable that will start a shadow copied application. The trick is, I want this starter program to have no external dependencies and not have to contain any knowledge about the program it has to start.
我的目标是创建一个可以启动影子复制应用程序的可执行文件。诀窍是,我希望这个启动程序没有外部依赖项,并且不必包含有关它必须启动的程序的任何知识。
I also want it to be the only executable in the directory. In other words, I want it to "run" a .dll assembly not an .exe assembly. (I can require that the name of the .dll file being loaded into a new AppDomain be the same everytime, like Main.dll or something like that.)
我还希望它成为目录中唯一的可执行文件。换句话说,我希望它“运行”一个 .dll 程序集而不是一个 .exe 程序集。(我可以要求加载到新 AppDomain 中的 .dll 文件的名称每次都相同,例如 Main.dll 或类似内容。)
It looked like AppDomain.ExecuteAssemblywould do exactly what I wanted. It says it will start execution at the "entry point specified in the .NET Framework header.".
看起来AppDomain.ExecuteAssembly会做我想要的。它说它将在“.NET Framework 标头中指定的入口点”开始执行。
When I try to use that function I get the error "Entry point not found in assembly 'DllApp'".
当我尝试使用该函数时,出现错误“在程序集‘DllApp’中找不到入口点”。
The starter program I have, just trying to run the assembly:
我有的启动程序,只是试图运行程序集:
static void Main()
{
AppDomain domain = AppDomain.CreateDomain( "DllApp" );
domain.ExecuteAssembly( "DllApp.dll" );
}
The application code, in a .dll file, with a default entry point:
.dll 文件中的应用程序代码,具有默认入口点:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault( false );
Application.Run( new Form1() );
}
}
This page on Main() functionssays that "Libraries and services do not require a Main method as an entry point". It doesn't say they cannothave a default entry point either.
Main() 函数上的这个页面说“库和服务不需要 Main 方法作为入口点”。它也没有说它们不能有默认入口点。
I have tried all the various permutations of public/private static void main, an int return type, string[] args as arguments, with a namespace, no namespace, static/non-static class, etc.
我已经尝试了 public/private static void main、int 返回类型、string[] args 作为参数、具有命名空间、没有命名空间、静态/非静态类等的所有各种排列。
I was able to change my code to inherit from MarshalByRefObject and then use CreateInstance to create an object, but that seems like it will more tightly couple the starter to the program it is supposed to start. If I could use ExecuteAssembly, the application being started would just need a static void Main, and that is really simple and hard to mess up.
我能够更改我的代码以从 MarshalByRefObject 继承,然后使用 CreateInstance 创建一个对象,但这似乎会使启动器与它应该启动的程序更紧密地耦合。如果我可以使用 ExecuteAssembly,那么正在启动的应用程序只需要一个静态的 void Main,这真的很简单而且很难搞砸。
Is it possible for a .dll assembly to have a default entry point, and for ExecuteAssembly to find it, or do I just have to resign myself to going another route?
.dll 程序集是否有可能有一个默认入口点,并让 ExecuteAssembly 找到它,或者我是否只需要让自己走另一条路?
采纳答案by Keith Nicholas
You can compile a .NET app as an exe (which is an assembly) and rename it to a .DLL and it will act as a normal .NET .dll assembly. It will then have your Entry point.
您可以将 .NET 应用程序编译为 exe(这是一个程序集)并将其重命名为 .DLL,它将充当普通的 .NET .dll 程序集。然后它会有你的入口点。
回答by Four_0h_Three
Short answer is no. a .DLL file is a dynamically linked library which is code called by another library. I guess what Keith said would technically work.. you could probably rename it to what ever you want even .txt or .pdf as long as you start the application in the proper manner. The main question I have is this; What are you trying to do?? Unless you're trying to write malware why would you want to do this? Not that I condone the writing of malware for bad purposes but I know people like to experiment in their own lab so I for one don't condemn it. If you're writing malware something like c++, c or assembler might be a better bet I guess C# could get the job done but meh...
简短的回答是否定的。.DLL 文件是一个动态链接库,它是由另一个库调用的代码。我猜 Keith 所说的从技术上讲是可行的。只要您以正确的方式启动应用程序,您就可以将其重命名为您想要的任何内容,甚至 .txt 或 .pdf。我的主要问题是这个;你想做什么??除非您尝试编写恶意软件,否则为什么要这样做?并不是说我宽恕出于恶意目的编写恶意软件,但我知道人们喜欢在自己的实验室中进行实验,因此我不谴责它。如果您正在编写诸如 c++、c 或汇编程序之类的恶意软件可能是更好的选择,我想 C# 可以完成这项工作,但是我...
回答by user3324444
I found the advice not so easy to follow. After some experimenting this is how I came to success:
我发现这些建议并不容易遵循。经过一些实验,这就是我成功的方式:
I created a console application with a simple main and included the rest of the code from my original DLL. Below is a simplified program which includes a DLL:
我创建了一个带有简单 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;
}
}
}
After compilation I renamed the generated .exe to a .DLL.
编译后,我将生成的 .exe 重命名为 .DLL。
In the mother program, which uses the DLL I first added the DLLTest.dll as a Reference, then I added the code to execute the 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à I could execute and add a breakpoint in the DLLTest.Main method and see that I could invoke the Main of DLLTest. Thanks for the discussion folks!
Violà 我可以执行并在 DLLTest.Main 方法中添加一个断点,并看到我可以调用 DLLTest 的 Main。谢谢大家的讨论!

