C #: how to embed a DLL in a resource file (there is no copy of dll in the program directory)

I have a C # application (project A) that requires X.dll. I added a project that creates X.dll for A as a reference in visual studio. I also added the assembly of the release of X.dll to the resource file as a binary file. I told Project A not to copy X.dll to the output directory.

Now I want A.exe to load, say β€œhey, I can’t find this file”, then look in the resource file and use Assembly.Load (byte []) to return X.dll. I have code that will re-mask the DLL back, however this code is never called.

I currently have a simple project just trying to get it to work. It will compile OK. When I run it, I get a FileNotFoundException on X.dll.

I have:

[STAThread] static void Main() { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } 

But the breakpoint at * CurrentDomain_AssemblyResolve * never hits. I get a FileNotFoundException right away. Of course, is there something I am missing?

0
source share
1 answer

This question seems very similar to what you are trying to achieve, and it worked for the seeker.

Combine .dll into C # assembly?

Are you doing something different? In particular, if you are targeting an old version of the .NET Framework, perhaps this is a hint for understanding why your application behaves differently.

In the other direction, use a tool such as the Fusion Log Viewer to analyze what happens when you try to load the assembly. This may give some advice. If you can get the journal information, posting it in a question can help someone figure this out.

EDIT: Another explanation, following your comment.

Well, now I think I know what the problem is.

In your Main method, you are referring to a type in another dll. But you do it in static code, i.e. Explicitly use code in code (as opposed to loading it dynamically by its name).

Why is this a problem? The CLR is trying to load your assembly to JIT Main itself.

Your FileNotFoundException was thrown, and Main was compiled. Main did not even start, so the event handler was not registered.

An easy way to check if I'm right is to change the code to something like this:

 static public void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += MyEventHandler; MyMain(); } // The CLR will actually try to load your assembly before even starting the execution // of this method. It needs the assembly in order to JIT the method because it has to // know the Thing type. static public void MyMain() { using(var thing = new Thing()) { // ... } } 

An important difference is that Main not related to another assembly, so JIT will not work and run it.

By the time MyMain is JIT'ed, your event handler is already in place, so you can manually load the assembly.

By the way, to avoid another possible similar trap, make sure that the class in which Main defined does not have a field with a type from another assembly, because in this case the CLR will try to load the assembly before the Main starts to compile it.

+10
source

Source: https://habr.com/ru/post/887093/


All Articles