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'
}
}
}
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'
}
}