I have simple C++/CLI console application that starts another process and read it's STDOUT and STDERR. It uses external (3rd party) libraries. I'm trying to embed them into .exe image to make standalone executable for deploy.
IlMerge output:
ilmerge /log /out:test1.exe test.exe ILMerge version 2.12.803.0 Copyright (C) Microsoft Corporation 2004-2006. All rights reserved. ILMerge /log /out:test1.exe test.exe Set platform to 'v2', using directory 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\..\v2.0.50727' for mscorlib.dll Running on Microsoft (R) .NET Framework v2.0.50727 mscorlib.dll version = 2.0.0.0 The list of input assemblies is: test.exe Trying to read assembly from the file 'test.exe'. Successfully read in assembly. There were no errors reported in test's metadata. Checking to see that all of the input assemblies have a compatible PeKind. test.PeKind = ILonly, Requires32bits All input assemblies have a compatible PeKind value. Using assembly 'test' for assembly-level attributes for the target assembly. Merging assembly 'test' into target assembly. Copying 4 Win32 Resources from assembly 'test' into target assembly. Transferring entry point '.mainCRTStartupStrArray(System.String[])' from assembly 'test' to assembly 'test1'. There were no errors reported in the target assembly's metadata. ILMerge: Writing target assembly 'test1.exe'. AssemblyResolver: Assembly 'test' is referencing assembly 'Microsoft.VisualC'. AssemblyResolver: Attempting referencing assembly's directory. AssemblyResolver: Did not find the assembly in referencing assembly's directory. AssemblyResolver: Attempting input directory. AssemblyResolver: Did not find the assembly in the 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 'Microsoft.VisualC'. Resolved assembly reference 'Microsoft.VisualC' to 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\..\v2.0.50727\Microsoft.VisualC.dll'. (Used framework directory.) Location for referenced module 'KERNEL32.dll' is '' Location for referenced module 'MSVCR100.dll' is '' Location for referenced assembly 'mscorlib' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll' There were no errors reported in mscorlib's metadata. Location for referenced assembly 'System' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\system.dll' There were no errors reported in System's metadata. Location for referenced assembly 'Microsoft.VisualC' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.VisualC.dll' There were no errors reported in Microsoft.VisualC's metadata. ILMerge: Done.
One thing was little confusing me - usage of Framework64 libraries considering x86 platform of the source application.
Startup of test1.exe leads to following output in console:
Unhandled Exception: System.TypeInitializationException: The type initializer for '' threw an exception. ---> .ModuleLoadException: The C++ module failed to load during registration for the unload events. ---> System.TypeInitializationException: The type initializer for ".ModuleUninitializer" threw an exception. ---> System.MissingMethodException: Method not found: "Void System.Threading.Monitor.Enter(System.Object, Boolean ByRef)". in System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(Delegate d) in System.AppDomain.add_DomainUnload(EventHandler value) in .ModuleUninitializer..ctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 255 in .ModuleUninitializer..cctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 217 --- End of inner exception stack trace --- in .RegisterModuleUninitializer(EventHandler handler) in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 292 in .LanguageSupport.InitializeUninitializer(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 426 in .LanguageSupport._Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 545 in .LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 697 --- End of inner exception stack trace --- in .ThrowModuleLoadException(String errorMessage, Exception innerException) in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 194 in .LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 707 in .cctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 749 --- End of inner exception stack trace ---
Any ideas?
AppDomain.CurrentDomain.AssemblyResolve
and a embedded resoruce instead. Mike Barnett, the author of ILMerge, comments on the article and says if he knew about that trick he would have never written ILMerge in the first place. Using Fody/Costura you can automate it during the build process. – Scott Chamberlain