How to register an C# class for COM?

5 days ago 5
ARTICLE AD BOX

I'd like to create an C# WPF library exposing some class to COM to use the class functionality from separate C++ project.

What I'd like to achieve is to have a WPF class which implements simple form like window where can i output the text messages using "shared". exposed function, say OutputText. What i want is to instantiate the class object what in turn just spawns the form text window, and the using the OutputText just send some text to it. That all have to be done from C++ application, using exposed COM class and CoCreateInstance function to get the things roll.

Here is the C# code:

using Microsoft.SqlServer.Server; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfCustomControlLibrary11 { [Guid("0E633447-41D9-4E28-A8F4-D24ADE2913CD")] public interface ICustomControl1 { void Test(); } [Guid("2002FDA9-E74A-4A88-B0E3-0CCD2C2695AD")] public class CustomControl1 : Control { static CustomControl1() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))); } public void Test() { MessageBox.Show("CustomControl1 - Test"); System.Console.Beep(); } } }

and the C++ code calling the exposed COM class:

#include <windows.h> #include <iostream> #include <thread> #import <WpfCustomControlLibrary11.tlb> //#include <WpfCustomControlLibrary11.tlh> EXTERN_C const CLSID CLSID_FileOpenDialog2; const GUID CLSID_riid = { 0xe633447, 0x41d9, 0x4e28, { 0xa8, 0xf4, 0xd2, 0x4a, 0xde, 0x29, 0x13, 0xcd } }; const GUID CLSID_rclsid = { 0x2002fda9, 0xe74a, 0x4a88, { 0xb0, 0xe3, 0xc, 0xcd, 0x2c, 0x26, 0x95, 0xad } }; using namespace std; using namespace WpfCustomControlLibrary11; HANDLE fileHandle; char buffer[100]; ICustomControl1* g_pMyComClient = NULL; HRESULT g_hr = NULL; void RunClient() { HRESULT hr = CoInitializeEx(NULL, //COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE COINIT_MULTITHREADED ); if (SUCCEEDED(hr)) { ICustomControl1* pMyComClient; hr = CoCreateInstance( CLSID_rclsid, NULL, CLSCTX_ALL, CLSID_riid, reinterpret_cast<void**>(&pMyComClient)); if (SUCCEEDED(hr)) { g_hr = hr; g_pMyComClient = pMyComClient; pMyComClient->Test(); } CoUninitialize(); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { sprintf(buffer, "WinMain - creating Client thread\n"); OutputDebugString(buffer); buffer[0] = '\0'; thread newThread(RunClient); newThread.join(); sprintf(buffer, "WinMain - Client thread has ENDED!\n"); OutputDebugString(buffer); buffer[0] = '\0'; return 0; }

I've performed below steps:

created the C# project using the WPF Custom Control Library(.NET Fremework) template.

checked "Make assembly COM-visible" in the project settings.

signed the library using the "sn -k Proj_Name.snk" and then providing this key in "signing" section in the project settings.

registered via RegAsm.exe

added to the GAC via gacutil /i

Now when i run the C++ Client i'm getting "REGDB_E_CLASSNOTREG Class not registered" error in response to CoCreateInstance call.

What's curious when i create just the Windows Forms project using the Windows Forms Control Library(.NET Fremework) template and follow above steps everything works great - CoCreateInstance returns no errors and the function test is successfully being called.

What could be the reason for the WPF project class NOT being registered and therefore used by C++ client while the Windows Forms project class registers and run flawlessly?

Thx for help in advance!

Read Entire Article