I have a .net (4.7.2) application that calls into a 3rd party native library using [DllImport("Foo.dll"...)]. That native Foo.dll is written in C++ and has a lot of dependencies: 90 assemblies, 360 MB (!) are shipped currently. I know that some dependencies are shipped, but not used anymore. Asking that 3rd party for cleanup had no effect, its getting more and more every few month.
Q: Is there any way to distinguish required, actively loaded native assemblies from dll bloat?
I have experimented with AppDomain.GetAssemblies() on application exit, but it one only returns managed assemblies.
I have experimented with DependencyWalker and its modern brother Dependencies, but it seems most of the truly required dependencies of Foo.dll are loaded on demand - only a small fraction shows up in those apps.
You could use Procmon to track assemblies being dynamically loaded.
But if some assemblies are only loaded if the feature is in the use, then you don't have any other choice than looking at the code (if you can) or go through all the possible code paths and track all loaded dlls.
Related
Mono.Cecil does not support mixed mode assemblies as of date, and even though it can read the .NET portion of such assemblies, it does not write such assemblies back to disk. What does it take to support a read->write roundtrip for mixed mode assemblies? (without making any changes to the x86/x64 assembly)
Please note I only need to work with .NET metadata and CIL, not the actualy x86/x64 assembly itself. I only need to modify some .NET classes within a mixed-mode assembly, therefore, I need to load it into objects using Cecil, make my changes, and then save it back, leaving the x86/x64 assembly code unmodified.
I'm assuming the x86/x64 assembly would be stored in a chunk, which could be simply read into a bytearray during parsing, and outputted back into the generated EXE when saving the assembly. Is it so simple?
From the FAQ:
Cecil can read mixed mode assemblies, but writing mixed mode assemblies is not supported
Mono.Cecil does not support writing mixed mode assemblies.
There is another library, dnlib, which does. The API is similar, but not the same, so it's not a drop-in replacement.
From the project's README.md
dnlib was created because de4dot needed a robust .NET assembly library that could handle all types of obfuscated assemblies. de4dot used to use Mono.Cecil but since Mono.Cecil can't handle obfuscated assemblies, doesn't fully support mixed mode assemblies, doesn't read .NET assemblies the same way the CLR does and many other missing features de4dot needed, dnlib was a necessity. The API is similar because it made porting de4dot to dnlib a lot easier.
GitHub repository is here: https://github.com/0xd4d/dnlib
My application includes SQLite.dll. How I make a single-executable application in C# WPF without installing via ClickOnce Application or any installation file setup.
How can I bundle System.Data.SQLite into my project so I can produce a single-executable application with no tag-along DLLs?
for the System.Data.SQLite.dll assembly you can embed it as a resource and then use Reflection.Load from the resource before it's used by any of your code so it's ready to go. Or handle when AssemblyResolve is called, then you load it from the resource.
With the SQLite.Interop.dll thats the hard part because it actually makes all the calls to the SQLLite C++ libraries, and the method used by the System.Data.SQLite assembly makes calls to the correct DLL based on X86 or x64. You could possibly couple the 1st part of this with this article to create a memory based load of the 2nd DLL but you'd need to replicate the initial checks for x64/x86 and .NET dll performs and then load the correct one. (You'd just embed both and load the correct one)
Is it good practice to bundle all required managed dlls as embedded resources to a .NET library project in order to ship just one dll?
Background:
I have created an API as a .NET dll (in C#), and it's working all fine. But the library has quite some dependencies on other managed libraries (around 15 dlls) so I need to distribute those as well.
When the users of my API have created an application they again have to make sure to distribute all those dlls along with the application. To me it would seem better if they had just one dll to consider.
The main downside I can see to using embedded dlls is that they must be unpacked to a temporary folder before being loaded dynamically, which may or may not have performance and robustness issues.
There are a lot of questions around this. What happens if you're expecting to load a platform-specific dependency (i.e. x86 vs. x64), or that's true about the app consuming your API? Does that mean that you need to include specific x86 vs x64 assemblies in your package as well? It becomes hairy quickly.
You should consider using ClickOnce deployment for these types of scenarios. Then, all of the dependencies would be packaged together.
Realistically, it's a problem for the API consumer to solve, not for the API producer. Your API might be less popular if it has a lot of external dependencies, but you'll have to make decisions there about what's really crucial to your API's success.
I know I'm not the first person to ask this question on Stack Overflow and I'm sure I won't be the last. But, after spending hours researching how to do this and then physically trying to do it, I'm near ready to give up.
I have a .NET Framework 4, C#, WinForms application that builds to an executable. I rely on many many many dlls. The dlls fall into multiple categories.
Libraries I have written with no dependencies of their own
Libraries I have written with dependencies on other libraries I've written
Libraries I have written with dependencies on third party dlls
Third party stand alone dlls
Third party dlls with their own dependencies on other dlls
So after I compile my application I have a directory with an executable and approximately 15 dlls.
I want to pack all the dlls into a single executable so that I can simply distribute a single executable.
I know that IlMerge is the typically suggested application to use for this, but I'm curious if there is something easier to use that is more intuitive and works accross both WinForms and WPF.
The problem here is that ILMerge only can merge .Net assemblies. Your file lame_enc.dll isn't a .Net assembly but a standard Windows dll and therefore can't be loaded by ILMerge.
To get around this you could embed lame_enc.dll in your assembly and then extract it when needed in your application. Check out this article for more info on that.
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
In the end, I went an entirely different direction.
I decided to use the Costura Visual Studio Extensions located here.
These extensions use a combination of two methods
Jeffrey Richter's suggestion of using embedded resources as a method of merging assemblies
Einar Egilsson's suggestion using cecil to create module initializers
What's nice here is that you simply install the extensions into Visual Studio. After doing that, for any project where you want to pack your DLLs into a single executable, simply select the project, click Project on the menu bar, Costura, Configure, and then OK. It will ask you to reload the project - click yes. Now whenever you build the project it will create just a single executable (or DLL if you are doing it on a library). Couldn't be more easy.
ILMerge only combines pure (not mixed-mode) CLR assemblies. It works by extracting all of the CIL modules and then relinking them into a single new assembly. Assembly resources are also recombined.
ILMerge cannot merge native executable code. lame_enc.dll is a native DLL file and does not contain any CIL modules, that's why you can't combine it.
If you want to pack your application into a single executable a workaround is to include lame_enc.dll as an assembly resource, then save lame_enc.dll to disk in a temp folder perhaps, and add the folder it was saved in to your application's PATH, so your [DllImport] runtime linker will be able to access it.
To address your exact issue, verify that the file C:\Release\lame_enc.dll exists and that it is in fact a .NET file. ILMerge can only merge .NET assemblies.
Now if you are only worried about distribution of your application, you may consider creating an installer to install all of the binaries, and not worry about merging them using ILMerge.
Another alternative to using ILMerge is to embed the binaries in an assembly as desribed here.
Is there any way to compile a .NET assembly into native code (i.e for x86) output, that is, without MSIL.
For what I understand if you just specify x86 as architecture this would only change the PE Header to point that out to the JIT, but still the assembly will contain MSIL and will be JITTed as needed.
NGen does produce assembly files for the specified architecture but it's not a compiler, it's designed to improve performance but you do still need the original DLL, the presence of the native image only serves to avoid JIT compiling the assembly but you just can't get that native image and use it, can you?
So, is there any way to actually compile from .NET to native machine code?
Spoon Studio (was named Xenocode before) seems to be able to do that: http://spoon.net/Studio/Features.aspx
RemoteSoft also have a product but the website looks quite old: http://www.remotesoft.com/linker/
You can do this using the new precompilation technology called .NET Native. Check it out here: http://msdn.microsoft.com/en-US/vstudio/dotnetnative
Currently it is only available for Windows Store Apps. It performs single component linking. So .NET Framework libraries are statically linked into your app. Everything is compiled to native and IL assemblies are no longer deployed.