When you develop a program, you often refer to some third-party DLLs, and then compile the resulting EXE files without running them independently from those DLLs.
However, many times we would like to develop a small tool that only needs an EXE to run perfectly. So what should we do?
The following is an easy way to do this without having to write a line of code.
Here we need to use a tool called Fody.costura. Fody.costura is a fody framework plug-in that can be installed through NuGet to VS engineering. After installation, you can package the DLL (or even PDB) files that your project relies on into an EXE file.
How to use
- In VS, the Costura.fody is installed through NuGet for the target EXE project. or install using the command line via the NuGet console: Install-package costura.fody-version 1.3.3
- Re-build the project.
When the build is complete, the newly generated EXE files are found in the project's output directory, and you will also find those DLLs still exist in the output directory. But don't worry, this exe has been able to run independently. You can remove all of these DLLs and then run EXE to try.
In addition, Fody.costura also supports some advanced features, such as:
- Temporary assembly file: Automatically unzip the DLL from the EXE to the folder system before running the EXE, and then load the DLL in a normal way.
- Merging unmanaged DLL:Fody.Costura can merge unmanaged DLLs, but it does not automatically fit. If your program involves an unmanaged DLL, you need to change the Fody.costura configuration file to show it what unmanaged DLLs you want to merge.
- Preload DLL:Fody.Costura can help you to preload certain DLLs at the start of a program, and you can even specify the order in which these DLLs are loaded.
All of these advanced features require you to modify the Fody.costura configuration file to be implemented, and the specific procedures can refer to its official documentation.
Well, the way Fody.costura is used has been introduced. If you're curious about how the Fody.costura works, you can look down.
Merging an unmanaged DLL
<?xml version= "1.0" encoding= "Utf-8"?>
<Weavers>
<Costura>
< unmanaged32assemblies>
sqlite.interop
</Unmanaged32Assemblies>
<unmanaged64assemblies >
sqlite.interop
</Unmanaged64Assemblies>
</Costura>
</Weavers>
Introduction to the principle of realization
When the CLR attempts to load an assembly but the load fails, it raises the Appdomain.assemblyresolve event. Our program can listen to this event and return the assembly that the CLR is trying to load in the handler function of this event, allowing the program to continue to function correctly.
When building a project, Fody.costura embeds all the DLLs referenced by the EXE into the exe file. When a program uses one of these DLLs while it is running (because the CLR cannot find the DLL file, causing the Appdomain.assemblyresolve event to be triggered), it extracts the required DLL from the embedded resource of the EXE file.
The following two functions are the Fody.costura code that implements this part of the logic.
public static void Attach () {var currentdomain = Appdomain.currentdomain;
Currentdomain.assemblyresolve + = (s, e) => resolveassembly (e.name); public static Assembly resolveassembly (string assemblyname) {if (Nullcache.containskey (AssemblyName)) {return n
ull;
var requestedassemblyname = new AssemblyName (AssemblyName);
var assembly = common.readexistingassembly (Requestedassemblyname);
if (assembly!= null) {return assembly;
} Common.Log ("Loading assembly ' {0} ' into the AppDomain", requestedassemblyname);
Assembly = Common.readfromembeddedresources (Assemblynames, Symbolnames, requestedassemblyname);
if (assembly = = null) {Nullcache.add (AssemblyName, true);
Handles retargeted assemblies like PCL if (requestedassemblyname.flags = = assemblynameflags.retargetable) {
Assembly = Assembly.Load (Requestedassemblyname);
} return assembly; }
As you can see, the Attach method listens for Appdomain.assemblyresolve events. The Assemblyresolve event handler function is executed when the CLR cannot successfully load an assembly. Assemblyresolve attempts to get the target assembly from the embedded resource of the loaded assembly and return it to the CLR through the Common.readfromembeddedresources method.
When you see this, you may ask,when was the Attach method implemented?
In fact, for the C # language, the CLR hides a big recruit--clr can execute some initialization code before each module (each assembly contains one or more modules) is loaded. Unfortunately, the C # language cannot control this part of the code. Fody.costura the IL code directly into the initialization function of the module inside the EXE assembly, and this part of the IL code actually executes the attach method. This allows the attach method to be invoked immediately after the EXE assembly is loaded.
The above is the Fody.costura realization principle simple introduction.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.