Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IRunningObjectTable.Register always sets pdwRegister to 65536, an invalid value

Tags:

c#

automation

com

I'm using IRunningObjectTable.Register and IRunningObjectTable.Revoke as shown in this tutorial. My VBScript client initially calls methods no problem, but when the C# COM server disposes, I always receive a "Value does not fall within the expected range" exception. This is due to the commented line below:

private const int ACTIVEOBJECT_STRONG = 0x0;

[DllImport("ole32.dll")]
private static extern int CreateBindCtx(int reserved,
    out IBindCtx bindCtx);

[DllImport("oleaut32.dll")]
private static extern int RegisterActiveObject
    ([MarshalAs(UnmanagedType.IUnknown)] object punk,
    ref Guid rclsid, 
    uint dwFlags, 
    out int pdwRegister);

// register instance so it appears in ROT
private static int Register<T>(T classToRegister) 
{  
    int pdwRegister;
    Guid guid = Marshal.GenerateGuidForType(typeof(T));

    RegisterActiveObject(classToRegister, 
        ref guid, 
        ACTIVEOBJECT_STRONG, 
        out pdwRegister);

    return pdwRegister;
}

// do stuff in VBScript before disposal calls Revoke with the stored 
// pdwRegister value from the method above

// revoke instance so it's removed from ROT
private static void Revoke(int pdwRegister)
{
    IBindCtx bc;
    CreateBindCtx(0, out bc);

    IRunningObjectTable rot;
    bc.GetRunningObjectTable(out rot);
    // EXCEPTION: pdwRegister is *always* 65536, an invalid value!
    rot.Revoke(pdwRegister);      
}

If I terminate the program and ignore the exception, the instance usually removes itself from the ROT. However, after some time, I've noticed multiple instances of my app's GUID in the ROT and my VBScript client starts failing on GetObject(, "my.id"). Any thoughts?

like image 448
Pakman Avatar asked Dec 06 '25 02:12

Pakman


1 Answers

The first one registered is always 65536, and that is correct.

Use

[DllImport("oleaut32.dll", PreserveSig = false)]
        public static extern void RevokeActiveObject(
            uint handle,
            IntPtr reserved);

And Not:

IBindCtx bc; 
    CreateBindCtx(0, out bc); 


IRunningObjectTable rot; 
bc.GetRunningObjectTable(out rot); 
// EXCEPTION: pdwRegister is *always* 65536, an invalid value! 
rot.Revoke(pdwRegister);       

And RevokeActiveObject needs to be called from the same thread and proc as it was registered in.

like image 81
Ron Avatar answered Dec 08 '25 16:12

Ron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!