COM servers implemented with .NET

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • molaughlen
    New Member
    • Feb 2008
    • 1

    #1

    COM servers implemented with .NET

    This is response to some poor guidance in response to this post:

    COM Interop - Localserver32 registry entries?

    The responses to the poster included such things as "use RegAsm.exe" and "don't do it that way!"

    I'm here to say that you can!

    First off, if you want to expose a .NET object to COM, you should understand how COM/Automation works: MSDN COM Documentation. Read through the Hello Sample article to see the magic in context.

    The MSDN documentation is pretty verbose and the majority of sample code isn't necessary in the .NET world, but it does demonstrate what hooks are needed. I'll highlight the functions that are involved:
    • CoRegisterClass Object
    • RegisterActiveO bject
    • RevokeActiveObj ect


    To access RegisterActiveO bject and RevokeActiveObj ect via .NET you'll need to use P/Invoke:
    Code:
    [DllImport("oleaut32.dll")]
    public static extern int RegisterActiveObject([MarshalAs(UnmanagedType.IUnknown)] object punk,
                    ref Guid rclsid, uint dwFlags, out int pdwRegister);
    [DllImport("oleaut32.dll")]
            public static extern int RevokeActiveObject(int dwRegister, object pvReserved);
    The output parameter, pdwRegister, is an identifier that is passed into RevokeActiveObj ect when the application is shutting down.

    In my sample code the call to RegisterActiveO bject is as follows:
    Code:
    Application app = new Application(); // can be any COMVisible class
    int dwCookie;
    Guid clsidApp = new Guid("9A10580E-0B90-407d-AE0B-8BDD8EA85892");
    int retVal = NativeMethods.RegisterActiveObject(app, ref clsidApp, 0, out dwCookie);
    But wait there's more! In addition to registering your .NET object instance in the ROT, you need to register the Type of the object via .NET v2.0's System.Runtime. InteropServices .RegistrationSe rvices class:
    Code:
    RegistrationServices regServices = new RegistrationServices();
    int dwCookieType;
    dwCookieType = regServices.RegisterTypeForComClients([INDENT]typeof(Application), RegistrationClassContext.LocalServer, RegistrationConnectionType.SingleUse);
    [/INDENT]
    When the application shuts down, you'll need to clean up:
    Code:
    NativeMethods.RevokeActiveObject(dwCookie, null);
    regServices.UnregisterTypeForComClients(dwCookieType);
    Once you've got these functions in place, the class must be registered in Windows. Here's what my reg file looks like:

    Code:
    [HKEY_CLASSES_ROOT\AutomationApp.Application]
    @="AutomationApp.Application"
    
    [HKEY_CLASSES_ROOT\AutomationApp.Application\CLSID]
    @="{9A10580E-0B90-407D-AE0B-8BDD8EA85892}"
    
    [HKEY_CLASSES_ROOT\CLSID\{9A10580E-0B90-407D-AE0B-8BDD8EA85892}]
    @="AutomationApp.Application"
    
    [HKEY_CLASSES_ROOT\CLSID\{9A10580E-0B90-407D-AE0B-8BDD8EA85892}\LocalServer32]
    @="C:\PATH\TO\EXE\AutomationApp.exe"
    This is truly the very tip of an enormous iceberg, but the MSDN documentation won't lead you astray.
  • hegge
    New Member
    • Apr 2008
    • 1

    #2
    Thanks for the great example molaughlen. I managed to get this to port this and get it to work in VB.NET 2005 Express. The EXE-file registers itself on launch and can be called with GetObject from any COM-compatible application

    One problem though, when the EXE is not running, I'll instantiate it with CreateObject. The EXE COM Server is then launched as defined in LocalServer32.

    The problem is that the COM Server takes command of the calling application (Excel for example) and won't let me work with Excel in the background until I close the COM Server again. Excel is giving me the error that it is waiting for an OLE-action to be completed in another application

    Do I need to start a new thread or what is the problem? I want to be able to continue to work in the calling application (Excel) even when the EXE Server is running.

    Thankful for any help with this issue,

    Regards
    /hegge

    Comment

    Working...