regsvr32 未注册 COM 调度接口

regsvr32 not registering COM dispinterface

我的系统是 Windows 10 64 位秋季创作者版 Visual Studio 2017 Professional。

我有一个具有以下 IDL (ISomeInterface.idl) 的 COM 接口:

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

我用这个命令编译的:

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

然后我创建一个模块定义文件(ISomeInterface.def):

LIBRARY     "ISomeInterface"

EXPORTS
    DllGetClassObject       PRIVATE
    DllCanUnloadNow         PRIVATE
    DllRegisterServer       PRIVATE
    DllUnregisterServer     PRIVATE

然后我使用这些命令构建我的界面 DLL:

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

当前正在使用此命令注册接口:

C:\Windows\SysWOW6432\regsvr32 ISomeInterface.dll

然后我为我的 C# 客户端生成我的 Interop 程序集:

sn -k Interop.ISomeInterface.snk

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

然后使用 regasm 注册。

我的问题是调度接口 _ISomeInterfaceEvents 没有正确注册。其他一切似乎都在注册表中显示正常。如果我添加这些条目,一切正常:

[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"

我缺少什么来正确注册调度接口?

---- 编辑 1

我的 ATL 服务上的 rgs 脚本如下所示:

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

我将以下内容添加到我的服务应用程序的 rgs 脚本中,当我 运行 /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'
        }
    }