Make .NET methods visible to COM

J

Janiek Buysrogge

Hello,

I followed the instructions on
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/callnetfrcom.asp
to call .NET class methods from the ActiveX Test Container
(tstcon32.exe) and I can load my control, but there aren't any methods
I can invoke.

However, in ActiveXplorer I can view the methods on the component
(screenshot:
http://idaho.cybernited.be/upload/televic/ActiveXplorer.JPG), but this
tool doesn't support invoking them.

Am I forgetting somehting ?

Any help appreciated.

Here's my code:

the interface:

using System;
using System.Collections.Generic;
using System.Text;

namespace COMVisibleMethods
{
public interface ICOMCallable
{
int SumOfTwo(int a, int b);
string GetCurrentDateTime();
}
}

the code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32;

namespace COMVisibleMethods
{
public partial class Math : UserControl, ICOMCallable
{
public Math()
{
InitializeComponent();
}

public string GetCurrentDateTime()
{
return DateTime.Now.ToLongDateString() + " " +
DateTime.Now.ToLongTimeString();
}

public int SumOfTwo(int a, int b)
{
return a + b;
}

[ComRegisterFunction()]
public static void RegisterClass(string key)
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I
don't need it
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);

// And create the 'Control' key - this allows it to show
up in
// the ActiveX control container
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();

// Finally close the main key
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
k.DeleteSubKey("Control", false);

// Next open up InprocServer32
RegistryKey inprocServer32 =
k.OpenSubKey("InprocServer32", true);

// And delete the CodeBase key, again not throwing if
missing
k.DeleteSubKey("CodeBase", false);

// Finally close the main key
k.Close();
}
}
}


-
JB
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Usually I decorate my COM's visible classes with:
[ClassInterface(ClassInterfaceType.None)]

[Guid("A0F6A88F-F20E-445f-8F80-95EA780AAB52")]


Not sure if this is what you are missing though.


--
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

Janiek Buysrogge said:
Hello,

I followed the instructions on
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/callnetfrcom.asp
to call .NET class methods from the ActiveX Test Container
(tstcon32.exe) and I can load my control, but there aren't any methods
I can invoke.

However, in ActiveXplorer I can view the methods on the component
(screenshot:
http://idaho.cybernited.be/upload/televic/ActiveXplorer.JPG), but this
tool doesn't support invoking them.

Am I forgetting somehting ?

Any help appreciated.

Here's my code:

the interface:

using System;
using System.Collections.Generic;
using System.Text;

namespace COMVisibleMethods
{
public interface ICOMCallable
{
int SumOfTwo(int a, int b);
string GetCurrentDateTime();
}
}

the code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32;

namespace COMVisibleMethods
{
public partial class Math : UserControl, ICOMCallable
{
public Math()
{
InitializeComponent();
}

public string GetCurrentDateTime()
{
return DateTime.Now.ToLongDateString() + " " +
DateTime.Now.ToLongTimeString();
}

public int SumOfTwo(int a, int b)
{
return a + b;
}

[ComRegisterFunction()]
public static void RegisterClass(string key)
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I
don't need it
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);

// And create the 'Control' key - this allows it to show
up in
// the ActiveX control container
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();

// Finally close the main key
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
k.DeleteSubKey("Control", false);

// Next open up InprocServer32
RegistryKey inprocServer32 =
k.OpenSubKey("InprocServer32", true);

// And delete the CodeBase key, again not throwing if
missing
k.DeleteSubKey("CodeBase", false);

// Finally close the main key
k.Close();
}
}
}


-
JB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top