【问题标题】:C# 4.0 Merge .dll assembly with .NETC# 4.0 将 .dll 程序集与 .NET 合并
【发布时间】:2011-06-05 23:53:34
【问题描述】:

我决定放弃我的other question,因为我想到了一个新的想法,使用 Jeffrey Richter 在this page 上编写的方法将 .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);
    }
}
        ;

我应该将资源名称更改为其他名称吗?我是否正确添加了它(在正确的位置)?

现在的问题是,它仍然无法找到并加载程序集,我不确定我做错了什么。任何帮助将不胜感激。

【问题讨论】:

  • 只是好奇;为什么还要费心(有效地)静态链接 DLL?
  • 因为我不想分发我的程序将 10-15 个用户认为无用的文件。
  • 为什么用户仍然在程序文件中挖掘?只需将它们安装到子目录中即可。我的意思是,“DLL”中的“DL”代表“动态链接”。

标签: c# .net dll assemblies merge


【解决方案1】:

你的问题和这个很相似:C#: How to embed DLL into resourcefile (no dll copy in program directory)

基本上,您的AppDomain.AssemblyResolve 事件处理程序没有被调用,因为Main 编译失败。即使它确实编译了,附加事件处理程序也应该是你在 main 中做的第一件事。

我对上述问题的回答有一个有效的代码示例,并解释了为什么您的代码不起作用。

【讨论】:

    【解决方案2】:

    使用调试器。在 AssemblyResolve 分配和 lambda 主体上设置断点。单步执行代码。

    是的,为时已晚。移动作业。如果 SingleInstanceController 在这样的 DLL 中,则 Main() 方法甚至永远不会启动。将该代码移动到单独的辅助方法中,并为其赋予 [MethodImpl(MethodImplOptions.Noinlining)] 属性。

    在单个文件中分发您的程序已经得到很好的支持,它不需要任何代码,也不需要合并 DLL。还负责桌面快捷方式、文件关联以及在旧机器上安装 .NET。它叫做 setup.exe

    【讨论】:

    • 是的,感谢您完全无视我的问题。我问为什么我的代码不工作或我做错了什么,而不是“我是否应该将 .dll 文件与我的应用程序一起分发”。我有理由不使用一堆 .dll 文件分发 .EXE 文件。另外,setup.exe 是从哪里来的?我的应用程序是一个相对较小且可移植的应用程序,我什至不想使用它。
    • 我没有忽略你的问题,你忽略了答案。尝试阅读的不仅仅是最后一段。在调试问题之前,您不会得到完美的答案。
    • “直到你调试你的问题”
    • 是你不知道调试器怎么用的问题?当你单步执行程序时发生了什么?我给出了答案,但在您尝试之前,您无法在您的眼前看到它。
    • “我尽量避免使用调试器”。我不敢相信我刚刚读到...
    【解决方案3】:

    在 AppDomain 尝试解析引用之前,即在入口点和第一行中,挂钩到 AssemblyResolve 事件。

    嵌入的资源名称以应用程序名称开头,后跟资源名称。 例如:ConsoleApplication.Test.dll。

    【讨论】:

    • 我不太清楚你的第一行是什么意思,你能解释一下吗? (对不起,我是 C# 的新手,没有太多经验)。
    • 将 AppDomain.CurrentDomain.AssemblyResolve += .... 移动到 Main 方法的第一行。
    • 我收到此错误:“无法加载文件或程序集 'Files, Version=2.3.4025.2210, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。无效的指针(来自 HRESULT 的异常: 0x80004003 (E_POINTER))" 当我这样做时,并重命名我的资源名称。
    • 替换字符串 resourceName = "AssemblyLoadingAndReflection." + 新的 AssemblyName(argsx.Name).Name + ".dll"; with String resourceName = String.Format("MyApp.{0}", args.Name);
    • 错误仍然存​​在,即使我添加了 String resourceName = String.Format("MyApp.{0}", args.Name) + ".dll";也。这肯定表明它找不到程序集,但我想不出它会这样做的任何原因。我添加了对该文件的引用并将其嵌入并将代码移至您所说的第一行。
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    相关资源
    最近更新 更多