Problems when compiling and running code that uses CertEnroll with .NET 4.0 and x64
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 CATest
Error 17 The type 'CERTENROLLLib.CX509ExtensionKeyUsageClass' has no constructors defined C:\CATest\CATest\Form1.cs 44 59 CATest
Error 19 The type 'CERTENROLLLib.CX509ExtensionEnhancedKeyUsageClass' has no constructors defined C:\CATest\CATest\Form1.cs 45 79 CATest
Error 11 The type 'CERTENROLLLib.CX509EnrollmentClass' has no constructors defined C:\CATest\CATest\Form1.cs 41 41 CATest
Error 25 The type 'CERTENROLLLib.CX509EnrollmentClass' has no constructors defined C:\CATest\CATest\Form1.cs 186 41 CATest
Error 1 The type 'CERTENROLLLib.CX509CertificateRequestPkcs10Class' has no constructors defined C:\CATest\CATest\Form1.cs 36 55 CATest
Error 9 The type 'CERTENROLLLib.CX500DistinguishedNameClass' has no constructors defined C:\CATest\CATest\Form1.cs 40 44 CATest
Error 13 The type 'CERTENROLLLib.CObjectIdsClass' has no constructors defined C:\CATest\CATest\Form1.cs 42 39 CATest
Error 15 The type 'CERTENROLLLib.CObjectIdClass' has no constructors defined C:\CATest\CATest\Form1.cs 43 37 CATest
Error 7 The type 'CERTENROLLLib.CCspInformationsClass' has no constructors defined C:\CATest\CATest\Form1.cs 39 40 CATest
Error 5 The type 'CERTENROLLLib.CCspInformationClass' has no constructors defined C:\CATest\CATest\Form1.cs 38 38 CATest
Error 23 The type 'CERTCLIENTLib.CCertRequestClass' has no constructors defined C:\CATest\CATest\Form1.cs 128 43 CATest
Error 21 The type 'CERTCLIENTLib.CCertConfigClass' has no constructors defined C:\CATest\CATest\Form1.cs 127 41 CATest
Error 4 Interop type 'CERTENROLLLib.CX509PrivateKeyClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 37 49 CATest
Error 18 Interop type 'CERTENROLLLib.CX509ExtensionKeyUsageClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 44 63 CATest
Error 20 Interop type 'CERTENROLLLib.CX509ExtensionEnhancedKeyUsageClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 45 83 CATest
Error 12 Interop type 'CERTENROLLLib.CX509EnrollmentClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 41 45 CATest
Error 26 Interop type 'CERTENROLLLib.CX509EnrollmentClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 186 45 CATest
Error 2 Interop type 'CERTENROLLLib.CX509CertificateRequestPkcs10Class' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 36 59 CATest
Error 10 Interop type 'CERTENROLLLib.CX500DistinguishedNameClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 40 48 CATest
Error 14 Interop type 'CERTENROLLLib.CObjectIdsClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 42 43 CATest
Error 16 Interop type 'CERTENROLLLib.CObjectIdClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 43 41 CATest
Error 8 Interop type 'CERTENROLLLib.CCspInformationsClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 39 44 CATest
Error 6 Interop type 'CERTENROLLLib.CCspInformationClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 38 42 CATest
Error 24 Interop type 'CERTCLIENTLib.CCertRequestClass' cannot be embedded. Use the applicable interface instead. C:\CATest\CATest\Form1.cs 128 47 CATest
Error 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)
Comments
- Anonymous
January 19, 2012
You can leave "Embed Interop Types" to "True".Instead ofCX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10Class();You can useCX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10(); - Anonymous
May 16, 2012
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.