interfacecomregsvr32midl

regsvr32 not registering COM dispinterface


My system is a Windows 10 64-bit fall creators edition with Visual Studio 2017 Professional.

I have a COM interface with the following IDL (ISomeInterface.idl):

import "oaidl.idl";
import "ocidl.idl";

[
    object,
    uuid(61E246F6-3F22-404B-8EA8-E4D13F3206D6),
    pointer_default(unique)
]
interface ISomeInterface : IUnknown
{
    HRESULT DoSomething();
}

[
    uuid(7EF22D33-5C29-4D32-BFBC-0B276C5F7427),
    version(1.0),
    helpstring("ISomeInterface 1.0 Type Library")
]
library ISomeInterfaceLib
{
    importlib("stdole2.tlb");
    [
        uuid(E6ED57C9-002C-4C63-8780-51C7E4A436CA),
        version(1.0),
        helpstring("_ISomeInterfaceEvents Interface")
    ]
    dispinterface _ISomeInterfaceEvents
    {
    properties:
    methods:
        [id(1)] HRESULT SendSomeMessage([in] BSTR sSomeMessage);
    };
    [
        uuid(BC91D238-B0E1-4FA2-AAC8-195D761DF9DC),
        version(1.0),
        helpstring("ISomeInterface Class")
    ]
    coclass ISomeInterfaceImpl
    {
        [default] interface ISomeInterface;
        [default, source] dispinterface _ISomeInterfaceEvents;
    };
};

Which I compile with this command:

midl /iid "ISomeInterface_i.c" /env win32 /h "ISomeInterface.h" /W1 /char signed /tlb "Release\ISomeInterface.tlb" /Oicf /D "NDEBUG" /robust /nologo /proxy "ISomeInterface_p.c" ISomeInterface.idl

Then I create a module definition file (ISomeInterface.def):

LIBRARY     "ISomeInterface"

EXPORTS
    DllGetClassObject       PRIVATE
    DllCanUnloadNow         PRIVATE
    DllRegisterServer       PRIVATE
    DllUnregisterServer     PRIVATE

And I build my interface DLL using these commands:

cl /c /Zi /W1 /WX- /O2 /Oy- /D WIN32 /D REGISTER_PROXY_DLL /D NDEBUG /D _WINDLL /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Release\\" /Fd"Release\vc100.pdb" /Gd /TC /analyze- /errorReport:prompt dlldata.c ISomeInterface_i.c ISomeInterface_p.c

link "/OUT:Release\ISomeInterface.dll" rpcns4.lib rpcrt4.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "/DEF:ISomeInterface.def" /MANIFEST "/ManifestFile:Release\ISomeInterface.dll.intermediate.manifest" "/MANIFESTUAC:level='asInvoker' uiAccess='false'" "/PDB:Release\ISomeInterface.pdb" /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT "/IMPLIB:Release\ISomeInterface.lib" /MACHINE:X86 /DLL Release\dlldata.obj Release\ISomeInterface_i.obj Release\ISomeInterface_p.obj

The interface is currently being registered using this command:

C:\Windows\SysWOW6432\regsvr32 ISomeInterface.dll

Then I generate my Interop assembly for my C# clients:

sn -k Interop.ISomeInterface.snk

tlbimp "Release\ISomeInterface.tlb" /keyfile:"Interop.ISomeInterface.snk" /out:"InteropDlls\Interop.ISomeInterface.dll" /namespace:Foo.Interop /sysarray

Which is then registered using regasm.

My issue is that the dispinterface _ISomeInterfaceEvents is not being properly registered. Everything else seems to be showing up OK in the registry. If I add these entries it all works:

[HKEY_CLASSES_ROOT\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}]
@="_ISomeInterfaceEvents"

[HKEY_CLASSES_ROOT\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"

[HKEY_CLASSES_ROOT\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\TypeLib]
@="{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}"
"Version"="1.0"

[HKEY_CLASSES_ROOT\WOW6432Node\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}]
@="_ISomeInterfaceEvents"

[HKEY_CLASSES_ROOT\WOW6432Node\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"

[HKEY_CLASSES_ROOT\WOW6432Node\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\TypeLib]
@="{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}"
"Version"="1.0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}]
@="_ISomeInterfaceEvents"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{FCCDE505-1C5E-406F-BD91-068BF1E9D7AA}\TypeLib]
@="{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}"
"Version"="1.0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}]
@="_ISomeInterfaceEvents"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\Interface\{FCCDE505-1C5E-406F-BD91-068BF1E9D7AA}\TypeLib]
@="{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}"
"Version"="1.0"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}]
@="_ISomeInterfaceEvents"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\Interface\{E6ED57C9-002C-4C63-8780-51C7E4A436CA}\ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\Interface\{FCCDE505-1C5E-406F-BD91-068BF1E9D7AA}\TypeLib]
@="{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}"
"Version"="1.0"

What am I missing to register the dispinterface properly?

---- Edit 1

My rgs script on my ATL service looks like this:

HKCR
{
    Foo.ISomeInterface.1 = s 'ISomeInterface Class'
    {
        CLSID = s '{BC91D238-B0E1-4FA2-AAC8-195D761DF9DC}'
    }
    Foo.ISomeInterface = s 'ISomeInterface Class'
    {    
        CLSID = s '{BC91D238-B0E1-4FA2-AAC8-195D761DF9DC}'    
        CurVer = s 'Foo.ISomeInterface.1'
    }
    NoRemove CLSID
    {
        ForceRemove {BC91D238-B0E1-4FA2-AAC8-195D761DF9DC} = s 'ISomeInterface Class'
        {
            ProgID = s 'Foo.ISomeInterface.1'
            VersionIndependentProgID = s 'Foo.ISomeInterface'
            LocalServer32 = s '%MODULE%'
            {
                val ServerExecutable = s '%MODULE_RAW%'
            }
            TypeLib = s '{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}'
            val AppID = s '%APPID%'
            Version = s '1.0'
        }
    }
}

Solution

  • I added the following to the rgs script on my service application and the interface is now being registered when I run the /RegServer

        ForceRemove {E6ED57C9-002C-4C63-8780-51C7E4A436CA} = s '_ISomeInterfaceEvents'
        {
            ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}'
            TypeLib = s '{7EF22D33-5C29-4D32-BFBC-0B276C5F7427}'
            {
                val Version = s '1.0'
            }
        }