I\'m testing out ILMerge for a new project, and although the .exe file seems to be created correctly, it won\'t run.
I have installed ILMerge via the .msi installer (fou
Perhaps this will not solve your problem, but I think that it is good to verify, that your ilmerged executable doesn't contain references to merged libraries. You can check this with ILSpy (http://wiki.sharpdevelop.net/ILSpy.ashx) - just disassemble your ilmerged executable and check in the tree what assemblies are in references. ILSpy can also help you to verify that your ilmerged executable contains classes from merged assemblies.
Next option could be also to debug assembly bindings when trying to start your ilmerged application (http://msdn.microsoft.com/en-us/library/e74a18c4%28v=VS.100%29.aspx).
You could also try to debug ilmerged assembly to find out if application crashes even before calling main function, or perhaps somewhere inside.
I think that identifying particular type which cannot be found could help to fix the problem.
After a few hours of fighting with this issue I deleted my project folder and did a fresh pull from git. I tried cleaned and rebuilt my project and it the same issue. I then compared my coworkers project and inside the *\Library\Build*, I was missing the Results folder. After adding the folder \Library\Build\Results my solution built with no errors.
ILMerge is great if you wrote all of the assemblies that you're trying to merge, and you know that none of them are making assumptions about assembly organization. But under many circumstances (especially ones where heavy reflection or the Dynamic Language Runtime are involved), ILMerge just doesn't work. Sometimes things fail in surprising and mysterious ways.
When ILMerge fails, Jeffrey Richter has a more reliable way to get applications with multiple DLL dependencies to be deployable as a single assembly.
It isn't without trade-offs, but even the ILMerge author, Mike Barnett, said in the comment thread on that blog post "As the author of ILMerge, I think this is fantastic! If I had known about this, I never would have written ILMerge."
If you can use Richter's method, you won't trip over most of the reflection or dynamism traps.
The implementation steps
AppDomain.CurrentDomain.AssemblyResolve
event.You do part 3 as follows:
var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
return Assembly.Load(new BinaryReader(resourceStream).ReadBytes(int.MaxValue));
Check your event viewer for any detailed error messages.
Wrap the body of your void Main(string args[])
method with
try
{
...
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Also try changing your platform target to x86 for example.
You shouldn't need to specify the .net framework directories on the /lib
and /targetplatform
command line switches if you specify /targetplatform:v4
.
A fully self-contained executable can be created in Visual Studio 2010 easily, and this method does not require ILMerge at all.
Steps:
After this Visual Studio will auto-create a new class called Resources, which you have to use in your new project.
Then you have to compile your program with Visual Studio and that's it.
static void Main(string[] args)
{
// Load your assembly with the entry point from resources:
Assembly start = Assembly.Load((byte[]) Properties.Resources.NameOfDllOrExeInYourResources);
Type t = start.GetType("Foo.Bar.Program");
// Install the resolver event
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
// Find Program.Main in the loaded assembly
MethodInfo m = t.GetMethod("Main", BindingFlags.Public | BindingFlags.Static);
// Launch the application
m.Invoke(null, new object[] { args });
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyName = new AssemblyName(args.Name).Name.Replace('.', '_');
// Locate and load the contents of the resource
byte[] assemblyBytes = (byte[]) Properties.Resources.ResourceManager.GetObject(assemblyName, Properties.Resources.Culture);
// Return the loaded assembly
return Assembly.Load(assemblyBytes);
}