I'm trying to create a merged version of FakeItEasy that includes Castle.Core. I read about ILMerge and it seemed like it was the solution I needed. After downloading and building FakeItEasy I copied all the files I needed (FakeItEasy.dll (.NET4), Castle.Core.dll (.NET4), ilmerge.exe, FakeItEasy.snk) to the same folder. I then ran the following command:
ilmerge
/keyfile:FakeItEasy.snk
/out:..\FakeItEasy.dll
/t:library
/targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319
FakeItEasy.dll Castle.Core.dll
And got the following result:
An exception occurred during merging:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at System.Compiler.Writer.MscorsnStrongNameSignatureGeneration(String wszFilePath, String wszKeyContainer, Byte[] pbKeyBlob, Int32 cbKeyBlob, IntPtr ppbSignatureBlob, IntPtr pcbSignatureBlob)
at System.Compiler.Writer.WritePE(String location, Boolean writeDebugSymbols, Module module, Boolean delaySign, String keyFileName, String keyName)
at System.Compiler.Writer.WritePE(CompilerParameters compilerParameters, Module module)
at ILMerging.ILMerge.Merge()
at ILMerging.ILMerge.Main(String[] args)
If I leave off the "/keyfile:FakeItEasy.snk" the merged assembly is created just fine, but that doesn't help me as I need a signed version.
I've also tried specifying the target platform as:
/targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319
but the results were the same.
I recently ran into this issue when setting up a project on a new machine running Windows 8 64-bit. I was previously developing in a Windows 7 32-bit virtual machine and had no issue. The ILMerge command is being run as a post-build event. Since Visual Studio is a 32-bit process I was also able to replicate the behavior in a 32-bit Visual Studio Command Prompt on the Windows 8 64-bit machine using the same ILMerge command used in the post-build event.
ILMerge.exe
/keyfile:public.snk
/targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
/t:exe
/ndebug
/out:Result.exe Source.exe Other.dll
I've done a fair amount of work interfacing .NET applications and native C++ libraries, so I'm very familiar with the exception message An attempt was made to load a program with an incorrect format.
This indicates a bitness issue where, for example, a 32-bit process attempts to load a 64-bit library. That exact situation is what I believe is going on here. Since this is a 64-bit machine I also tried the ILMerge command in a 64-bit Visual Studio Command Prompt. Interestingly, but not totally surprisingly, the same command that generates the exception in the 32-bit prompt works fine in the 64-bit prompt.
I'm using an snk file that contains only public key information when developing, so I'm delay signing the merged assembly. I then looked at the available command switches for ILMerge and discovered the /delaysign
switch. Adding this switch to the ILMerge command alleviates the issue when running ILMerge from a 32-bit process.
ILMerge.exe
/keyfile:public.snk
/delaysign
/targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
/t:exe
/ndebug
/out:Result.exe Source.exe Other.dll
What's even more interesting is that when using an snk file with a full public/private key pair, the ILMerge command works just fine without the /delaysign
switch. So it appears that the exception is generated when using an snk file with only public key information and when ILMerge is launched from a 32-bit process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With