Hi all,
The other day a customer of mine was trying to compile and run this CertEnroll sample of mine: How to create a certificate request with CertEnroll and .NET (C#)
I had developed this sample against .NET 2.0 some time ago, and it compiled and run just fine.
But my customer created a .NET 4.0 project with Visual Studio 2010, he added the required references to CERTCLIENTLib (CertCli 1.0 Type Library in certcli.dll) and CERTENROLLLib (CertEnroll 1.0 Type Library in certenroll.dll), and when he tried to copile in Debug mode with Any CPU platform, he got many errors like this:
"
Error 3 The type 'CERTENROLLLib.CX509PrivateKeyClass' has no constructors defined C:\CATest\CATest\Form1.cs 37 45 CATestError 17 The type 'CERTENROLLLib.CX509ExtensionKeyUsageClass' has no constructors defined C:\CATest\CATest\Form1.cs 44 59 CATestError 19 The type 'CERTENROLLLib.CX509ExtensionEnhancedKeyUsageClass' has no constructors defined C:\CATest\CATest\Form1.cs 45 79 CATestError 11 The type 'CERTENROLLLib.CX509EnrollmentClass' has no constructors defined C:\CATest\CATest\Form1.cs 41 41 CATestError 25 The type 'CERTENROLLLib.CX509EnrollmentClass' has no constructors defined C:\CATest\CATest\Form1.cs 186 41 CATestError 1 The type 'CERTENROLLLib.CX509CertificateRequestPkcs10Class' has no constructors defined C:\CATest\CATest\Form1.cs 36 55 CATestError 9 The type 'CERTENROLLLib.CX500DistinguishedNameClass' has no constructors defined C:\CATest\CATest\Form1.cs 40 44 CATestError 13 The type 'CERTENROLLLib.CObjectIdsClass' has no constructors defined C:\CATest\CATest\Form1.cs 42 39 CATestError 15 The type 'CERTENROLLLib.CObjectIdClass' has no constructors defined C:\CATest\CATest\Form1.cs 43 37 CATestError 7 The type 'CERTENROLLLib.CCspInformationsClass' has no constructors defined C:\CATest\CATest\Form1.cs 39 40 CATestError 5 The type 'CERTENROLLLib.CCspInformationClass' has no constructors defined C:\CATest\CATest\Form1.cs 38 38 CATestError 23 The type 'CERTCLIENTLib.CCertRequestClass' has no constructors defined C:\CATest\CATest\Form1.cs 128 43 CATestError 21 The type 'CERTCLIENTLib.CCertConfigClass' has no constructors defined C:\CATest\CATest\Form1.cs 127 41 CATestError 4 Interop type 'CERTENROLLLib.CX509PrivateKeyClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 37 49 CATestError 18 Interop type 'CERTENROLLLib.CX509ExtensionKeyUsageClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 44 63 CATestError 20 Interop type 'CERTENROLLLib.CX509ExtensionEnhancedKeyUsageClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 45 83 CATestError 12 Interop type 'CERTENROLLLib.CX509EnrollmentClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 41 45 CATestError 26 Interop type 'CERTENROLLLib.CX509EnrollmentClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 186 45 CATestError 2 Interop type 'CERTENROLLLib.CX509CertificateRequestPkcs10Class' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 36 59 CATestError 10 Interop type 'CERTENROLLLib.CX500DistinguishedNameClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 40 48 CATestError 14 Interop type 'CERTENROLLLib.CObjectIdsClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 42 43 CATestError 16 Interop type 'CERTENROLLLib.CObjectIdClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 43 41 CATestError 8 Interop type 'CERTENROLLLib.CCspInformationsClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 39 44 CATestError 6 Interop type 'CERTENROLLLib.CCspInformationClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 38 42 CATestError 24 Interop type 'CERTCLIENTLib.CCertRequestClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 128 47 CATestError 22 Interop type 'CERTCLIENTLib.CCertConfigClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 127 45 CATest"
To get rid of these compilation errors we changed "Embed Interop Types" to "False" in the Properties of the CERTCLIENTLib and CERTENROLLLib references.
Still, when we tried to run the code, we got this exception:
System.BadImageFormatException was unhandled Message=Could not load file or assembly 'Interop.CERTENROLLLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. Source=CATest FileName=Interop.CERTENROLLLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null StackTrace: at CATest.Form1.createRequestButton_Click(Object sender, EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at CATest.Program.Main() in C:\_PUBLIC\CATest\CATest\Program.cs:line 17 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()"
I still didn't have time to figure out why this happens, but if you compile against x86 platform instead of Any CPU platform (which makes the code to run against x64 platform on x64 systems by default), it will work fine.
I hope this helps. Please, if someone knows why this happens, please share it with the community. And if someone needs to run this code in x64 with .NET 4.0 and we still don't know the answer, open a Technical Support case with us so we can spend the time required to investigate this. Thank you.
Regards,
Alex (Alejandro Campos Magencio)
You can leave "Embed Interop Types" to "True".
Instead of
CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10Class();
You can use
CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10();
As for compilation - explanation is easy - VS generates Interop that matches bitness of your projects compilations - so if any single project in your solution is compied as x86 - you will get interop x86 which will cause badimageformatexception in runtime.