Craig W.
Craig W.

Reputation: 18175

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.

Upvotes: 5

Views: 1785

Answers (2)

Jon
Jon

Reputation: 1

I started getting this error when I upgraded to VS 2015 from VS 2013 and tried to build a project that had always built fine (ILMerge is executed as part of the build). The answer above reminded me that private keys require administrative access. Then I remembered that my new VS 2015 shortcut wasn't setup to "Run as administrator". Once I restarted VS 2015 as an administrator, the ILMerge part of the build worked fine.

Upvotes: 0

harlam357
harlam357

Reputation: 1491

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.

Upvotes: 2

Related Questions