1

我有一个使用插件的C#控制台程序nugetSocketIO4Net

当我构建exe并将其移动到我的 Windows 2008 服务器时,它不起作用,而在我的本地计算机上,它可以工作。

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'SocketIOClient, Version=0.6.26.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

有什么办法可以将我所有的依赖项烘焙到exe?


我试着做:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var resName = "converter.SocketIOClient.dll";
    var thisAssembly = Assembly.GetExecutingAssembly();
    using (var input = thisAssembly.GetManifestResourceStream(resName))
    {
        return input != null
             ? Assembly.Load(StreamToBytes(input))
             : null;
    }
};

但这没有用。也许我resourceName弄错了?

4

2 回答 2

1

是的。

使用AppDomain.AssemblyResolve在运行时“水合”嵌入式程序集。

Github 上的这个项目SQLDiagCmd包含执行此操作的示例。它基于Jeffrey Ricther 的方法

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
{ 

   String resourceName = "AssemblyLoadingAndReflection." + 
                          new AssemblyName(args.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); 
   } 
}; 

“技巧”是嵌入式程序集所在的位置,并且(如您所见),用于在处理程序中引用它的字符串AssemblyResolve。【我现在没时间,以后再看……】

于 2013-11-11T23:46:39.707 回答
1

这是我的示例,它基于将一个 dll 作为嵌入式资源嵌入到另一个 dll 中,然后从我的代码中调用它,但有一些有用的屏幕截图。

using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using MyEmbbedFile;

namespace ProjectNameSpace
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                var resName = "ProjectNameSpace.MyEmbbedFile.dll";
                var thisAssembly = Assembly.GetExecutingAssembly();
                using (var input = thisAssembly.GetManifestResourceStream(resName))
                {
                    return input != null
                         ? Assembly.Load(StreamToBytes(input))
                         : null;
                }
            };
        }

        private void button1_Click(object sender, EventArgs e)
        {

            MyEmbbedFileApp app = new MyEmbbedFileApp();
            app.DoStuff();
        }

        private static byte[] StreamToBytes(Stream input)
        {
            var capacity = input.CanSeek ? (int)input.Length : 0;
            using (var output = new MemoryStream(capacity))
            {
                int readLength;
                var buffer = new byte[4096];

                do
                {
                    readLength = input.Read(buffer, 0, buffer.Length);
                    output.Write(buffer, 0, readLength);
                }
                while (readLength != 0);

                return output.ToArray();
            }
        }
    }
}

您还需要做 2 件事:

您仍然需要确保将程序集添加为参考,以便您的代码编译。只要确保它不会复制到输出目录即可。

在此处输入图像描述

您需要做的第二件事是将您对项目的引用添加为普通文件。然后将其构建操作设置为属性下的嵌入式资源。

在此处输入图像描述

于 2013-11-12T02:13:02.453 回答