This article is a mirror article of machine translation, please click here to jump to the original article.

View: 219600|Reply: 43

[WinForm] .net/c# Use Costura.Fody to package the DLL into the EXE

[Copy link]
Posted on 4/14/2018 2:41:49 PM | | | |
Winform/wpf development inevitably refers to many third-party DLLs, but every time you package it, you need to copy the files in the Debug directory to the customer or share them, which is not very convenient to use. I have tried several software to merge dll files before, such as ILMerge, Enigma Virtual Box, etc., but until I learned about "Costura.Fody", I felt that the world was much better~

The following is a program written by Winform, referencing the two DLLs of "HttpHelper.dll" and "Newtonsoft.Json.dll", when we generate the program, there will be an exe file and these two DLL files, which makes people feel very uncomfortable, and if there is one less DLL, the program may report an exception, as shown in the figure below:



The link below is the previous usage (not recommended)

C# packages the dll into the exe's program
http://www.itsvse.com/thread-2841-1-1.html
(Source: Architect_Programmer)



Using the Costura.Fody tool, you can merge the source DLL into the target EXE

Project Homepage: https://github.com/Fody/Costura

How to use, directly install the nuget package:



Once you have successfully added Costura.Fody, the solution will automatically add FodyWeavers.xml file.

Regenerate the solution, you can see your success in the program generation directory, all the DLLs are perfectly merged into the exe, you can directly copy the exe file to the client to run independently. As shown below:

1>------ All rebuilds have been started: Project: itsvse, Configuration: Debug Any CPU ------
1>    Fody: Fody (version 2.0.0.0) Executing
1>      Fody/Costura:           No reference to 'Costura.dll' found. References not modified.
1>      Fody/Costura:           Embedding 'E:\project\itsvse\itsvse\HttpHelper.dll'
1>      Fody/Costura:           Embedding 'E:\project\itsvse\itsvse\Newtonsoft.Json.dll'
1>    Fody:   Finished Fody 609ms.
1>    Fody:   Skipped Verifying assembly since it is disabled in configuration
1>    Fody:   Finished verification in 3ms.
1>  itsvse -> E:\project\itsvse\itsvse\bin\Debug\itsvse.exe
========== Regenerate all: 1 succeeds, 0 fails, and 0 ========== skipped





As can be seen from the above picture, the generated file does not contain Newtonsoft.Json.dll, HttpHelper.dll and Costura.dll are not generated, only two files, itsvse.exe can be run directly without errors! (The PDB file can be deleted).

Let's use the ILSpy tool to decompile our program and take a look at the generated source code, as shown in the figure below:



Introduction to the implementation principle

When the CLR tries to load an assembly but fails to load, it raises the AppDomain.AssemblyResolve event. Our program can listen for this event and return the assembly that the CLR is trying to load in the event handler so that the program can continue to function normally.

Fody.Costura embeds all the DLLs referenced by the EXE into the EXE file when building the project. When a program uses one of these DLLs during execution (the AppDomain.AssemblyResolve event is triggered because the CLR cannot find the DLL file), the required DLL is extracted from the embedded resources of the EXE file.


You can see that the Attach method listens to the AppDomain.AssemblyResolve event. When the CLR fails to load an assembly successfully, the AssemblyResolve event handler is executed. AssemblyResolve attempts to get the target assembly from the loaded assembly's embedded resource via the Common.ReadFromEmbeddedResources method and returns it to the CLR.

Seeing this, you may ask, when was the Attach method implemented?

In fact, for the C# language, the CLR hides a big trick - the CLR can execute some initialized code before each module (each assembly contains one or more modules) is loaded. Unfortunately, the C# language has no control over this part of the code. Fody.Costura injects IL code directly into the initialization function of the internal module of the EXE assembly, and this part of the IL code actually executes the Attach method. This way, once the EXE assembly is loaded, the Attach method can be called immediately.

The above is a brief introduction to the implementation principle of Fody.Costura.


Advanced configuration

These configurations are added or modified in CosturaFodyWeavers.xml files.

CreateTemporaryAssemblies
Default: false
This embeds the embedded file into disk before loading it into memory. This is useful for certain scenarios where you want to load an assembly from a physical file.

IncludeDebugSymbols
Default: true
Controls whether the .pdbs of the reference assembly are also embedded.

DisableCompression
Default: false
Embedded assemblies are compressed by default and uncompressed when loaded. You can turn off compression using this option.
Note: Be sure to turn off this property when referencing non-standard DLLs, or encrypted DLLs. Otherwise, it will lead to the situation that the exe cannot be opened. This was discovered when I was using DSkin.dll.

DisableCleanup
Default: false
As part of Costura, embedded components are no longer included in the build. This cleanup can be turned off.

LoadAtModuleInit
Default: true
Costura is loaded by default as part of module initialization. The flag disables the behavior. Make sure you can use CosturaUtility.Initialize() somewhere.

ExcludeAssemblies
How to use: ExcludeAssemblies="DLL1| DLL2"
A list of assembly names to exclude from the default action of "embed all copy local references".

IncludeAssemblies
How to use: IncludeAssemblies="DLL1| DLL2"
A list of assembly names included in the default action of Embedding All Copy Local References.

Unmanaged32Assemblies&Unmanaged64Assemblies
How to use it: Unmanaged32Assemblies="DLL1| DLL2" Unmanaged64Assemblies="DLL1| DLL2"
Mixed-mode assemblies cannot be loaded in the same way as managed assemblies. Therefore, to help Costura identify which components are in mixed mode, and in which environments to load them, their names should be included in one or both lists. Do not include .exe or .dll in the name.

PreloadOrder
Usage: PreloadOrder="DLL1| DLL2"
Local libraries can be automatically loaded by Costura. To include a local library, include it in your project as an embedded resource called a folder costura32 or costura64 depending on the instability of the library. Alternatively, you can specify the loading order in which the preloaded libraries are loaded. When you mix temporary components from disk, they are also preloaded.

CosturaUtility
How to use:




CosturaUtility is a class that allows you to manually initialize the Costura system in your own code.This is mainly for scenarios where the module initialization program does not work, such as libraries and Mono.


Finally, download the source code in the text:

Tourists, if you want to see the hidden content of this post, pleaseReply





Previous:StreamReader solution for garbled characters when reading files
Next:Solutions for conflicts between Hyper-V and VirtualBox and VMware
Posted on 6/7/2018 9:35:19 AM |
Try this method about integrating dependency component Dll into C# compiled EXE!

If it's easy to use, remember to praise it! Haha, this, just add Dll to the resource file, simple and practical! (I don't understand, I can come up with a tutorial) @小渣渣

 Landlord| Posted on 6/6/2018 10:30:42 AM |
If you sign a program, you will receive the following error:

1>MSBUILD : error : Fody: An unhandled exception occurred:
1>MSBUILD : error : Exception:
1>MSBUILD: error: Unable to get a public key for StrongNameKeyPair.
1>MSBUILD : error : StackTrace:
1>MSBUILD: error: at System.Reflection.StrongNameKeyPair.ComputePublicKey()
1>MSBUILD: error: in System.Reflection.StrongNameKeyPair.get_PublicKey()
1>MSBUILD: error: in Mono.Cecil.ModuleWriter.WriteModuleTo(ModuleDefinition module, Disposable'1 stream, WriterParameters parameters)
1>MSBUILD: error: in Mono.Cecil.ModuleDefinition.Write(String fileName, WriterParameters parameters)
1>MSBUILD: error: In InnerWeaver.WriteModule() position C:\projects\fody\FodyIsolated\ModuleWriter.cs: line number 18
1>MSBUILD: error: In InnerWeaver.Execute() position C:\projects\fody\FodyIsolated\InnerWeaver.cs: line number 86
1>MSBUILD : error : Source:
1>MSBUILD : error : mscorlib
1>MSBUILD : error : TargetSite:
1>MSBUILD : error : Byte[] ComputePublicKey()
1>MSBUILD : error :
1>    Fody:   Finished Fody 551ms.


There seems to be no solution, refer to the article:

https://github.com/Fody/ExtraConstraints/issues/5

https://github.com/Fody/Costura/issues/194


Don't rely on strong names to stay safe.

So it seems pointless to go the extra mile to protect something that isn't a security feature

 Landlord| Posted on 4/17/2018 1:02:12 PM |
xxhh Posted on 2018-4-17 11:35
After installing Costura.Fody directly in vs NuGet, I dragged a Windows Media Playe player to generate two built-in dlls to delete or report ...

Windows Media Player controls are com components, I don't know if "Costura.Fody" supports them.

1: You should see if "Costura.Fody" supports "com components"
2: Ignore the two DLLs that are packaged, as for how to ignore xml should be set, please refer to the official documentation for details
Posted on 4/17/2018 10:29:52 AM |
Download to see the XML configuration
Posted on 4/17/2018 10:33:34 AM |
The owner wants to ask you if I can get the video and dll together into an exe plugin
 Landlord| Posted on 4/17/2018 11:16:15 AM |
xxhh Posted on 2018-4-17 10:33
The owner wants to ask you if I can get the video and dll together into an exe plugin
...

You can do this, you can set the video property to "Embedded Resources", and then read the resource file.
Posted on 4/17/2018 11:35:51 AM |
Xiao Zhao posted on 2018-4-17 11:16
You can do this, you can set the video property to "Embedded Resources", and then read the resource file. ...

I dragged a Windows Media Playe player directly after installing Costura.Fody in vs NuGet and produced two built-in dlls to delete or report an error  
Posted on 4/17/2018 11:57:09 AM |
Does XML still need to be set?     
Posted on 4/17/2018 5:42:31 PM |
Xiao Zhao posted on 2018-4-17 11:16
You can do this, you can set the video property to "Embedded Resources", and then read the resource file. ...

Landlord or me, I want to ask, I put the video into the embedded resource, what reads out is a byte array, is there any way to put it in the player and play it directly (I don't want to write to the local to play in the read path, the video is more than the big card)
 Landlord| Posted on 4/17/2018 8:52:16 PM |
xxhh Posted on 2018-4-17 17:42
Landlord or me, I want to ask, I put the video into the embedded resource, and what reads out is a byte array, is there any way to put it in the player and play it directly ( ...

It is not recommended to make a large video into a resource file, you can see if there is any other way for the player to directly pass in byte[]
Posted on 4/18/2018 8:08:48 AM |
Xiao Zhazha Posted on 2018-4-17 20:52
It is not recommended to make a large video into a resource file, you can see if there is any other way for the player to directly pass in byte[] ...

None of them read video addresses and want to ask you what good ideas you have
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com