Link to home
Start Free TrialLog in
Avatar of mcainc
mcainc

asked on

Including .dll files into compiled .EXE (C#)

I can't seem to wrap my head around this. I have 2 dll files that I would like to include in my project so that they are not required to be distributed with the application. I also don't want these dlls to be written to the execution directory at run-time if possible.

I've added the dlls to Resources but at this point I'm stuck.

How do I make use of these dlls at runtime? It doesn't seem possible to add a Reference from a local Resource...
Avatar of Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger)
Flag of Canada image

Resources are used for everything that is not code (strings, images, sounds, reports). They cannot contain code, compiled or not.

If you want dlls to be incorporated in your application, you first need Visual Studio 2010. This option was not available in previous versions.

And only COM dlls can be included. .NET dlls must be either already installed in a proper location on the users computer or distributed with the application.

In order include a COM dll in your application in Visual Studio 2010, you add the dll to your References, not your Resources. References can be added with a right click on the Reference item in the Solution Explorer.

Once the Reference has been added to the project, select it and set its Embed Interop Types to True in the Properties window.
Avatar of kaufmed
Actually, it is possible to load a DLL as a compiled resource. It makes it a tad more difficult to use, but it is possible. You wouldn't be adding references to the DLL at that point, IIRC. You would instead use dynamic loading of the library.
@kaufmed

Could you at least give a hint on how you could prevent having to distribute the dll with the application through dynamic loading?

What I know as dynamic loading enables you to link with a dll that was not referenced. It does not include the dll into the .exe at compilation.
Yes. I planned to shortly. I'm at my Linux box at the moment, so it's rather a hindrance to try and do so from that environment  ; )
I too work in different environments and languages. It's very easy to get confuse while working, even more so here where we something answer in a rush.

I know the feeling :-)
All, please have a look at the linked project. I have presented two approaches to using the resource in code--the first being less preferrable, but the latter requiring a slight tweak to existing code.

ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mcainc
mcainc

ASKER

wow thank you this helps tremendously!!
NP. Glad it helped  = )
Avatar of mcainc

ASKER

So just to clarify...

I will distribute a "common.dll" file that is actually only making references to the actual DLL which we've embedded into the applications Resources? So the real DLL is essentially packed into the application / hidden?
I will distribute a "common.dll" file that is actually only making references to the actual DLL which we've embedded into the applications Resources? So the real DLL is essentially packed into the application / hidden?
It's not making a reference to the "hidden" DLL. The hidden DLL contains a class declared to implement the interface ILibrary (in my example). Since that class implements the interface, you can cast an instance of it to type ILibrary (that's the as ILibrary part). Since the main project knows about ILibrary classes, you can work with an ILibrary even though at compile time your main project knows nothing of the types contained by hidden DLL. At compile time of your library, you set up your library to implement the appropriate functions defined by ILibrary. Later, at runtime, when you load the DLL into the app domain, .NET will know that your library implements ILibrary, and this is why you can safely cast to ILibrary once you create an instance using Activator.CreateInstance.

One "problem" I ran into is that when I initially added the DLL as a resource, I hadn't yet included the logic to implement the ILibrary interface. I later modified the code accordingly, but I forgot to update the resource. When I got to the line that casted the instance to type ILIbrary, the cast failed. This was because the original DLL wasn't defined to implement ILibrary. Make sure when you add your resource that you are adding the most up-to-date version of the DLL to prevent subtle errors similar to what I encountered  = )

I forgot to mention:  the Resources folder of my example shows two resources, but that is in error. I mistakenly added the wrong file. I deleted from the Properties->Resources page, but I forgot that it would still show in the Resources folder.
To clarify a bit more, the only references that occur in the sample are Library referencing Common.dll and Main referencing Common.dll. This is to grant each respective project compile-time knowledge of what the ILibrary is defined as. Main knows nothing of Library's internal code in the sample. Main only knows about ILibrary's code. The most Main knows about Library is that it is a resource and, at the cost of simplicity of the demo, there is a namespace and class called "_27301950_Library.LibraryClass". This is hard-coded into Main's code and there's probably a more elegant way of handling this.
I forgot to mention:  the Resources folder of my example shows two resources, but that is in error. I mistakenly added the wrong file. I deleted from the Properties->Resources page, but I forgot that it would still show in the Resources folder.
The resource in error for that folder is 27301950_Common.dll.