Sunday, March 18, 2012

Creating single EXE that depends on many DLL files in C# using visual studio

Many applications consist of an EXE that depends on many DLL files. When deploying an application all files must be deployed. So carrying all dependent DLL files for an exe during deployment is a problem and you may miss one of the dependent DLL file. To overcome on this problem you can create a single deployable EXE in Visual Studio. In visual studio, we can make configuration of EXE in such a way that, we can load an assembly at runtime that is located in a folder that is not the bin folder of the application. You do not have to put an assembly that an application must use at runtime in the bin folder of the application. You can put the assembly in any folder on the system, and then you can refer to the assembly at runtime. Following procedure explain the same –

The technique uses Appdomain’s “AssemblyResolve” event to achieve it. First, identify all the DLL files that your EXE file depends on. Then add these DLL files in one of the folder in your project. For example, I am using following DLL files in my application which I have added in dll folder in my application –

Add the reference of these DLL files in the application from the folder. In my case I added reference from “dll” folder. Then in the “dll” folder, select each DLL file and open properties; change “Build Action” to “Embedded Resource”. This causes C# compiler to embed the DLL files into your EXE file and then you can deploy this one EXE file. At runtime, the CLR won’t be able to find the dependent DLL assemblies, which is a problem. The “AssemblyResolve” event fires whenever CLR tries to bind an assembly and fails. The “AssemblyResolve” event handler must return an [Assembly] object.

Also the call to event handler method registration must be the first statement and rest of the logic should be wrapped in another method. In my case, for example, I am generating bitmap image in Main method of my console application. Therefore my code segment in Main method is as follows –

//GHeatReducer.dll. - this name is retrievd from ILDasm tool and by opening GHeatReducer.exe in the ILDasm tool. In ILDASM tool select name rpesent against “.mresource” to write in GetManifestResourceStream method.“GHeatReducer” is the name of namespace and “dll” is the name of folder where DLL files to be referenced is present as shown in above screenshot.

I'm having a problem with this.. this is a small console application that solves a ProjectEuler problem. It requires the FSharp.PowerPack DLL.

I've done exactly as this article suggests. Add the fsharp.powerpack.dll file to the solution, changed the build action to "embedded resource". Added a reference to the dll file "..\ConsoleApplication1\dlls\FSharp.PowerPack.dll"

Yet, when I copy the ConsoleApplication1.exe from the debug folder (after doing a build), to a computer that doesn't have F# library installed, I get "Unhandled exception: system.io.fileloadexception: could not load file or assembly 'FSharp.PowerPack...." when running it...

Hey Wes,Assuming, you are using F# code only to load F# dll; as I don't know much about F#, Make sure that you have given correct path from .mresource in the code. Also make sure that, when you build your EXE, does it have size including the size of your DLL?

Hey Rao, in class library you will not find program.cs as this is for console application. For your scenario, the above code of main method and handler method will go in EXE and not in DLL_1. hope this helps.

Could not load file or assembly 'ServiceAgent, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependenciesAn expected resource in the assembly manifest was missing. (Exception from HRESULT: 0x80131532)

It might be the case that, Service Agent dll is also required to be added in the folder. Also make sure that, you are referring the correct path. Use ILDASM tool to reach to the manifest of serviceagent dll. When you build the EXE, does it have size including the size of serviceagent dll. If not then service agent is not getting added in the EXE. So add and then try. Hope this helps.

Followers

About Me

I am Kunal. Most Valuable Professional (MVP) in Microsoft Azure. Working with Software company in India wasting important moments of life in office...In free time (which I don't get usually)I write blogs and answers the forum questions. I was doing it just for timespass but now I have got addicted to blogging...Apart from work, I do variety of things which I can't tell here:).. I am trekker, singer, actor, painter, f1 racer, super hero in my dreams.. ...and now trying my luck with technologies...Keep posting...

Visitors

Disclaimer:

The information shared in this blog is the result of my personal experience with various technology platforms. In no way it represents the company I work for.
The information provided here is "AS IS" with no warranties, and confers no rights. This blog does not represent the thoughts, intentions, plans or strategies of my current employer or past empolyers or any other forums or community I belong to. It is fully my own opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.I have full rights to edit/modify/delete any content of this blog without any prior notice to public/followers/RSS readers of this blog.