dotnet / ILMerge

ILMerge is a static linker for .NET Assemblies.
MIT License
1.23k stars 170 forks source link

Unresolved assembly reference not allowed: Embedded DLLs #60

Open Grisgram opened 5 years ago

Grisgram commented 5 years ago

Hi,

we have a compiled exe with embedded DLLs (AppDomain.CurrentDomain.AssemblyResolve loads them from the resources) as we need an exe without any additional files in production.

This program almost never gets recompiled, so I google'd and found ILMerge to just change the version (build number) of the exe to match with the product release without compile.

Unfortunately above error shows up because it can't find the dependencies.

WHY do you need to find all dependencies if I just want to change the version number (using /ver:) ?

Can this be changed?

mike-barnett commented 5 years ago

Unfortunately, ILMerge resolves all dependencies for when it encounters a reference so it can get at the real definition (e.g., of a type). It turns out it probably didn't need to be written that way, but it is behavior baked way deep into the infrastructure it is built on top of. Have you tried ilrepack? It is built on top of a newer infrastructure that does not necessarily require resolving all references.

hrumhurum commented 5 years ago

The resolved references are still required due to the way .NET metadata is written to the assembly. There are a few situations where serialization is not possible without a resolved assembly (for example, boxed enums in custom attributes).

While ilrepack may minimize the 'eagerness' of assembly resolution, it still remains generally unavoidable.

mike-barnett commented 5 years ago

True. I was just trying to keep it simple. If the infrastructure is as lazy as possible about resolving references, then it is definitely possible that no references will be resolved as long as those situations (like the one you mention) are not encountered. But the stuff ILMerge is built on top of isn't lazy at all: it always (and eagerly) resolves all assembly references.

Grisgram commented 5 years ago

Hello there, thanks for your replies!

While we need to avoid recompiling that specific .exe file, I COULD manage it, that the original .dll's (that have been embedded) can exist as files in the same folder when I run ILMerge. I would copy that all together in a temp folder, run ILMerge and then delete everything except the exe.

The question is: Would that work? Does ILMerge change anything else but the version number if I use /ver: and /out: as the only parameters?

For us here the important part is, that nothing changes in the exe (an its dll's) except that version number. It shall just match the current build number. nothing else.

Grisgram commented 5 years ago

I just tried that by myself but it does not seem to work. Please see the log below. I executed this command line:

ilmerge Launcher.exe /ver:2.0.21 /out:_Launcher.exe /log:log.txt

ILMerge reported no error, but the version of the .exe afterwards was still "1.0.0.0" for the assembly and file version. The output file was 1kb larger than the original input file.

Here is the log:

============================================= Timestamp (UTC): 18.03.2019 06:15:37 ILMerge version 3.0.0.0 Copyright (C) Microsoft Corporation 2004-2006. All rights reserved. ILMerge Launcher.exe /ver:2.0.21 /out:_Launcher.exe /log:log.txt Set platform to 'v4', using directory 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319..\v4.0.30319' for mscorlib.dll Running on Microsoft (R) .NET Framework v4.0.30319 mscorlib.dll version = 4.0.0.0 The list of input assemblies is: Launcher.exe Trying to read assembly from the file 'C:\repo\Launcher\version-tmp\Launcher.exe'. Successfully read in assembly. There were no errors reported in Launcher's metadata. Checking to see that all of the input assemblies have a compatible PeKind. Launcher.PeKind = ILonly, Requires32bits, Prefers32bits All input assemblies have a compatible PeKind value. AssemblyResolver: Assembly 'Launcher' is referencing assembly 'xxx.xxx.SelfUpdate'. AssemblyResolver: Attempting referencing assembly's directory. Resolved assembly reference 'xxx.xxx.SelfUpdate' to 'C:\repo\Launcher\version-tmp\xxx.xxx.SelfUpdate.dll'. (Used referencing Module's directory.) AssemblyResolver: Assembly 'Launcher' is referencing assembly 'xxx.xxx.Toolbox'. AssemblyResolver: Attempting referencing assembly's directory. Resolved assembly reference 'xxx.xxx.Toolbox' to 'C:\repo\Launcher\version-tmp\xxx.xxx.Toolbox.dll'. (Used referencing Module's directory.) Using assembly 'Launcher' for assembly-level attributes for the target assembly. Merging assembly 'Launcher' into target assembly. Copying 7 Win32 Resources from assembly 'Launcher' into target assembly. Transferring entry point 'Unicope.AutoUpdate.Launcher.Program.Main(System.String[])' from assembly 'Launcher' to assembly 'DBLogViewer_Launcher'. There were no errors reported in the target assembly's metadata. ILMerge: Writing target assembly 'DBLogViewer_Launcher.exe'. AssemblyResolver: Assembly 'Launcher' is referencing assembly 'System.Core'. AssemblyResolver: Attempting referencing assembly's directory. AssemblyResolver: Did not find assembly in referencing assembly's directory. AssemblyResolver: Attempting input directory. AssemblyResolver: Did not find assembly in input directory. AssemblyResolver: Attempting user-supplied directories. AssemblyResolver: No user-supplied directories. AssemblyResolver: Attempting framework directory. Can not find PDB file. Debug info will not be available for assembly 'System.Core'. Resolved assembly reference 'System.Core' to 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319..\v4.0.30319\System.Core.dll'. (Used framework directory.) AssemblyResolver: Assembly 'Launcher' is referencing assembly 'xxx.xxx.Logging'. AssemblyResolver: Attempting referencing assembly's directory. Resolved assembly reference 'xxx.xxx.Logging' to 'C:\repo\Launcher\version-tmp\xxx.xxx.Logging.dll'. (Used referencing Module's directory.) Location for referenced assembly 'mscorlib' is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll' There were no errors reported in mscorlib's metadata. Location for referenced assembly 'System.Core' is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Core.dll' There were no errors reported in System.Core's metadata. Location for referenced assembly 'System.Windows.Forms' is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Windows.Forms.dll' There were no errors reported in System.Windows.Forms's metadata. Location for referenced assembly 'xxx.xxx.SelfUpdate' is 'C:\repo\Launcher\version-tmp\xxx.xxx.SelfUpdate.dll' There were no errors reported in xxx.xxx.SelfUpdate's metadata. Location for referenced assembly 'System.Drawing' is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Drawing.dll' There were no errors reported in System.Drawing's metadata. Location for referenced assembly 'System' is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\system.dll' There were no errors reported in System's metadata. Location for referenced assembly 'xxx.xxx.Toolbox' is 'C:\repo\Launcher\version-tmp\xxx.xxx.Toolbox.dll' There were no errors reported in xxx.xxx.Toolbox's metadata. Location for referenced assembly 'xxx.xxx.Logging' is 'C:\repo\Launcher\version-tmp\xxx.xxx.Logging.dll' There were no errors reported in xxx.xxx.Logging's metadata. ILMerge: Done.

mike-barnett commented 5 years ago

Hmm, that should have worked. Is there any way you can package the input assemblies into a zip file and send it to me so I can take a look? I thought that if it was updating the version then there should be something about that in the log. Can you try it with just a dummy, toy, assembly and see if it updates the version number correctly?

Grisgram commented 5 years ago

Unfortunately not. Those assemblies may not leave the network here. In the meantime we found another way through our build server (Bamboo). It's a bit a workaround, but it will do for now.

For the future (next major release) we will likely redesign a bit of the packaging we do currently, maybe ILMerge will work then.

Thanks for looking into it.

mike-barnett commented 5 years ago

Okay. If you are able to recreate the problem using assemblies that are able to share, then I'd be happy to look into it. Sorry for the problems!