当通过ATL创建COM对象时,默认的.rgs文件总是将对象注册到HKCR:
HKCR
{
...
}
如果该对象是第一次写入注册表,则写入 HKCR 相当于写入 HKLM,这将使该对象对所有用户全局可见。
从注册表维护的角度来看,这似乎是一个相当糟糕的主意,因为 HKCR/HKLM 会随着计算机上任何用户安装的任何 COM 对象而迅速崩溃,从而减慢所有用户的访问速度。此外,任何包括 COM 对象的部署模块都必须使用 UAC 在 Windows 上请求管理员提升,这会对可部署性产生不利影响。那么为什么ATL/COM要这样设计呢?
本文建议,为了在 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/