3

MIDL 编译器使用写入 HKEY_LOCAL_MACHINE 的注册例程为代理/存根生成代码。有什么方法(最好不破解 MIDL 生成的代码,并且不绕过所有生成的代码来支持自定义代码)在 HKEY_CURRENT_USER 中注册 MIDL 生成的 p/s?

另外:如果 p/s 和 COM 服务器都像这样按用户注册,这会起作用吗?我刚刚发现(在非常令人沮丧的 48 小时后)如果 COM 服务器是按用户注册的,那么在机器范围内注册的 ap/s 将无法正常工作。具体来说,在这些情况下,p/s 的异步调用逻辑(ICallFactory::CreateCall)会失败。

4

1 回答 1

0

使用 RegOverridePredefKey 是正确的答案。然后注册:

regsvr32 /n /i:user C:\src\myCode.dll

使用“/i:user”,regsvr32 调用您的“DllInstall”函数而不是 DllRegisterServer。

DllInstall 的示例实现:

extern "C" STDAPI DllInstall(BOOL bInstall, _In_opt_  LPCWSTR pszCmdLine)
{
    HRESULT hr = E_FAIL;
    static const wchar_t szUserSwitch[] = L"user";

    if (pszCmdLine != NULL)
    {
        if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)
        {
            ATL::AtlSetPerUserRegistration(true); // is this really needed??
        }
    }

    LSTATUS status = RegCreateKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Classes", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hkcu_classes, &disposition);
    if (status == ERROR_SUCCESS)
    {
        status = RegOverridePredefKey(HKEY_CLASSES_ROOT, hkcu_classes);
    }
    hr = HRESULT_FROM_NT(status);

    if (SUCCEEDED(hr))
    {
        if (bInstall)
        {
            hr = DllRegisterServer();
            if (FAILED(hr))
            {
                DllUnregisterServer();
            }
        }
        else
        {
            hr = DllUnregisterServer();
        }
    }
}
于 2021-04-13T22:03:45.837 回答