Background: I want to develop a Active X control(using winform), so other C++ and C# applications can use this active x control in their UI.
Problem: I've finished develop this control, and I can find the COM object in regedit.And MFC can use this active X well. However, in my winform application, I can find this active X control, and I also can add it in toolbox. But when I drag this to winform page, an exception is thrown:
Fail to create component 'Axhost'. The error message follows:
'System.Runtime.InteropServices.ComException(0x80029C4A):Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A(TYPE_E_CANTLOADLIBRARY))
......
(PS: To avoid compatibility issue, I build my Active x winform library with x86. The winform application which use Active X also selected as x86. The Target framework is both .NetFramework 4 Client Profile)
Would any one has idea on this problem ? Is there something wrong in my project or registration?
Details:
1 About how to build Active X control
1) check "Register for COM Interop" in Build option and check make Assembly COM visible in Assembly Information
2) Give some COM attribute to my class. Implement RegisterClass and UnregisterClass, so that this Com object can be recognized as a Active X control.
[ProgId("MyTest.UserControl")] [ClassInterface(ClassInterfaceType.AutoDispatch)] public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } [ComRegisterFunction()] public static void RegisterClass(string key) { StringBuilder sb = new StringBuilder(key); sb.Replace(@"HKEY_CLASSES_ROOT\", ""); // Open the CLSID\{guid} key for write access RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true); RegistryKey ctrl = k.CreateSubKey("Control"); ctrl.Close(); // Next create the CodeBase entry - needed if not string named and GACced. RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true); inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase); inprocServer32.Close(); k.Close(); } [ComUnregisterFunction()] public static void UnregisterClass(string key) { StringBuilder sb = new StringBuilder(key); sb.Replace(@"HKEY_CLASSES_ROOT\", ""); // Open HKCR\CLSID\{guid} for write access RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true); // Delete the 'Control' key, but don't throw an exception if it does not exist if (k == null) { return; } k.DeleteSubKey("Control", false); // Next open up InprocServer32 RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true); // And delete the CodeBase key, again not throwing if missing inprocServer32.DeleteSubKey("CodeBase", false); // Finally close the main key inprocServer32.Close(); k.Close(); } }
2 Registration
I use a bat to register, inside bat is:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe MyTestActiveX.dll /register /codebase /tlb
1) I've also try some good practice in Winform Active X like (http://www.codeproject.com/Articles/1256/Exposing-Windows-Forms-Controls-as-ActiveX-control). In these cases, the same as mine, Active X can work well in MFC application but can't drag in from toolbox to winform page.