C# 4.0 将 .dll 程序集与 .NET 合并
我决定让我的其他问题死掉,因为我使用 Jeffrey Richter 的方法想到了一个新想法 此页面 将 .dll 库合并到我的应用程序中。因此,我将 .dll 文件添加为嵌入式资源,并将其添加为参考。然后在 Program.cs 中(我不知道他发布的代码应该放在哪里),我添加了以下内容:
...
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
_in = args[1];
SingleInstanceController controller = new SingleInstanceController();
controller.Run(args);
AppDomain.CurrentDomain.AssemblyResolve += (sender, argsx) =>
{
String resourceName = "AssemblyLoadingAndReflection." +
new AssemblyName(argsx.Name).Name + ".dll";
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
;
我应该将 resourceName 更改为其他名称吗?我是否正确添加了它(在正确的位置)?
现在的问题是,它仍然无法找到并加载程序集,我不确定我做错了什么。任何帮助将不胜感激。
I decided to leave my other question to die, since I thought of a new idea using Jeffrey Richter's method written on this page to merge a .dll library to my application. So I added my .dll file as an embedded resource and also added it as a reference. Then in Program.cs (I have no idea where the code he posted is supposed to go), I added this:
...
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
_in = args[1];
SingleInstanceController controller = new SingleInstanceController();
controller.Run(args);
AppDomain.CurrentDomain.AssemblyResolve += (sender, argsx) =>
{
String resourceName = "AssemblyLoadingAndReflection." +
new AssemblyName(argsx.Name).Name + ".dll";
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
;
Am I supposed to change resourceName to something else? Have I added it correctly (in the right place)?
Now the problem is, it still fails to find and load the assembly and I'm not sure what I've done wrong. Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的问题与此非常相似: C#:如何将 DLL 嵌入到资源文件中(程序目录中没有 DLL 副本)
基本上,您的
AppDomain.AssemblyResolve
事件处理程序没有被调用,因为Main
无法编译。即使它确实编译了,附加事件处理程序也应该是您在 main.c 中做的第一件事。我对上述问题的回答有一个有效的代码示例,并解释了为什么您的代码不起作用。
Your problem is very similar to this one: C#: How to embed DLL into resourcefile (no dll copy in program directory)
Basically, your
AppDomain.AssemblyResolve
event handler did not get called becauseMain
failed to compile. Even if it did compile, attaching the event handler should be the first thing you do in main.My answer to the question above has a working code sample and explanation on why your code does not work.
使用调试器。在 AssemblyResolve 赋值和 lambda 主体上设置断点。单步执行代码。
是的,那已经太晚了。移动作业。如果 SingleInstanceController 位于这样的 DLL 中,则 Main() 方法甚至永远不会启动。将该代码移至单独的辅助方法中,并为其赋予 [MethodImpl(MethodImplOptions.Noinlined)] 属性。
将程序分发到单个文件中已经得到了很好的支持,它不需要任何代码,也不需要合并 DLL。还负责桌面快捷方式、文件关联以及在旧计算机上安装 .NET。它的名字叫setup.exe
Use the debugger. Set breakpoints on the AssemblyResolve assignment and the lambda body. Single step the code.
Yes, that's too late. Move the assignment. If SingleInstanceController is in such a DLL then the Main() method never even gets started. Move that code into a separate helper method and give it the [MethodImpl(MethodImplOptions.Noinlining)] attribute.
Distributing your program in a single file is already very well supported, it doesn't require any code nor merging DLLs. Also takes care of the desktop shortcut, the file associations and getting .NET installed on old machines. It's called setup.exe
在 AppDomain 尝试解析引用(即入口点和第一行中的引用)之前,挂钩 AssemblyResolve 事件。
嵌入资源名称以应用程序名称开头,后跟资源名称。
例如:ConsoleApplication.Test.dll。
Hook to the AssemblyResolve event before the AppDomain tries to resolve references i.e in the entry point and the first line.
The embedded resource name starts with the application name followed by the resource name.
ex: ConsoleApplication.Test.dll.