com - 为什么ATL COM注册默认为HKCR

标签 com registry uac atl

当通过ATL创建COM对象时,默认的.rgs文件总是将对象注册到HKCR:

HKCR
{
...
}

如果该对象是第一次写入注册表,则写入 HKCR 相当于写入 HKLM,这将使该对象对所有用户全局可见。

  1. 从注册表维护的角度来看,这似乎是一个相当糟糕的主意,因为 HKCR/HKLM 会随着计算机上任何用户安装的任何 COM 对象而迅速崩溃,从而减慢所有用户的访问速度。此外,任何包括 COM 对象的部署模块都必须使用 UAC 在 Windows 上请求管理员提升,这会对可部署性产生不利影响。那么为什么ATL/COM要这样设计呢?

  2. 本文建议,为了在 HKCU ( http://blogs.msdn.com/b/jaredpar/archive/2005/05/29/423000.aspx ) 下注册 COM 对象,必须更新 DllRegisterServer。如果我们简单地将 .rgs 文件中的 HKCR 更改为 HKCU,为什么它不起作用? ATL 会直接忽略它吗?既然如此,为何还要坚持使用HKCR?

最佳答案

通过DllRegisterServer进行注册预计将在设计上提供系统范围的注册和COM类可用性。

为了取代这种注册行为并按用户注册,在某些时候引入了另一种注册方法:DllInstall功能。当前的 ATL 实现了这种开箱即用的方式,通过为 DllInstall 函数提供的“用户”命令行开关提供每用户注册。

以下是从模板生成的新项目的代码(使用向导):

// DllInstall - Adds/Removes entries to the system registry per user per machine.
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);
        }
    }
    if (bInstall)
    {   
        hr = DllRegisterServer();
        if (FAILED(hr))
        {
            DllUnregisterServer();
        }
    }
    else
    {
        hr = DllUnregisterServer();
    }
    return hr;
}

要注册每个用户,您可以使用“regsvr32/i:user MyAtlProject.dll”。您可以自由选择您想要的注册方式,没有“差”和“好”的方法 - 您只是有多种选择。

关于com - 为什么ATL COM注册默认为HKCR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22742042/

相关文章:

c++ - 确定注册表项是否包含注册表值或子项的最佳方法是什么?

windows - 通常从提升的进程执行进程

c++ - COM 方法调用返回灾难性故障

windows - 通过 PowerShell 使用路径组件创建注册表项

python - 自动化 Excel 从 Python 获取 "TypeError: ' unicode' 对象不可调用“在 Range.Address 上

c# - 使用 C# 将值写入注册表

.net - C# : What are Partially Trusted Callers?

vb6 - 是否可以使用资源编辑器将 list 资源添加到 VB6 项目?

c++ - 如何在 Visual Studio C++ 2010 中将 BSTR 转换为 std::string?

asp.net - 来自 ASP.NET 的免注册 COM?