1

I have a C# console program that uses the nuget plugin SocketIO4Net

When I build the exe and move it to my Windows 2008 server, it doesn't work, whereas on my local machine, it works.

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.

Is there any way I can bake all my dependencies into the exe?


I tried doing:

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;
    }
};

But that didn't work. Perhaps I'm getting the resourceName wrong?

2 Answers2

1

Yes.

Use AppDomain.AssemblyResolve to 'hydrate' embedded assemblies at runtime.

This project SQLDiagCmd at Github contains an example of doing this. It is based on Jeffrey Ricther's method:

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); 
   } 
}; 

The 'trick' is where the embedded assembly is located and (as you have found), the string used to refer to it in the AssemblyResolve handler. [I don't have time right now but will look again later...]

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
1

Here is my example which is based off of Embedding one dll inside another as an embedded resource and then calling it from my code but has some helpful screenshots.

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();
            }
        }
    }
}

There are 2 other things you will need to do:

You will still need to make sure you add your assembly as a reference so your code compiles. Just make sure it does not copy to the output directory.

enter image description here

The second thing you need to do is add your reference to the project as a normal file. Then set it's build action to Embedded Resource under properties.

enter image description here

Community
  • 1
  • 1
Sam Plus Plus
  • 4,381
  • 2
  • 21
  • 43
  • Following those steps inflated the filesize of my .exe, but I still get the same error –  Nov 12 '13 at 16:55
  • I got it to work. I just had to add the dependencies that my dependency depended on. –  Nov 12 '13 at 17:20