Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating signed library with ILMerge throwing exception

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.

like image 967
Craig W. Avatar asked Nov 04 '22 20:11

Craig W.


1 Answers

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.

like image 135
harlam357 Avatar answered Nov 15 '22 05:11

harlam357