我对COM相关的编程相当新,我需要一个程序化的C ++解决方案来解决以下问题。远程机器上有COM +应用程序。此信息似乎仅保存在Windows下由%SYSTEMROOT%\ Registration维护的数据库中。以下代码实现了我想要的,但只能在本地机器上实现。
bool comslocal()
{
CoInitialize(NULL);
TRY_HRESULT(hr)
{
CComPtr<ICOMAdminCatalog> catalog;
hr = CoCreateInstance(CLSID_COMAdminCatalog,
NULL,
CLSCTX_ALL,
IID_ICOMAdminCatalog,
reinterpret_cast<void **>(&catalog));
CComPtr<ICatalogCollection> collection;
hr = catalog->GetCollection(_bstr_t(L"Applications"),
reinterpret_cast<IDispatch **>(&collection));
hr = collection->Populate();
long count;
hr = collection->get_Count(&count);
for (int i = 0; i < count; ++i)
{
CComPtr<ICatalogObject> object;
hr = collection->get_Item(i,
reinterpret_cast<IDispatch **>(&object));
_variant_t var;
hr = object->get_Name(&var);
std::wstring n(var.bstrVal);
std::wcout << L"Name: " << n << std::endl;
}
}
CATCH_HRESULT(hr)
{
std::wcout << L"FALSE LOL: " << std::hex << hr << std::dec << std::endl;
return false;
}
return true;
}
输出如下:
Count: 5
Name: COM+ Utilities
Name: COM+ QC Dead Letter Queue Listener
Name: COM+ Explorer
Name: COM+ Utilities (32 bit)
Name: System Application
为了从远程主机成功检索相同的信息,我需要对此代码进行哪些精确修改? 请尽可能提供一个工作示例。这里有许多变量,准确的文档很少。
假设我拥有源计算机上的用户帐户的凭据,并且该帐户是内置Administrators组的成员。解决方案必须明确使用这些凭据,因为代码需要在不保证隐式权限的各种条件下工作。出于我的测试目的,我目前正在使用远程Windows Server 2003 R2计算机及其内置管理员帐户。我的本地计算机是Windows Server 2008 R2,如果它是相关的。
我尝试了以下修改:
std::wcout << L"Connect" << std::endl;
ICatalogCollection* pRemoteRootCollection = NULL;
hr = pCatalog->Connect(_bstr_t(server), (IDispatch**)&pRemoteRootCollection);
但是,此处connect()的结果始终为80070005(ACCESS DENIED)。通过LogonUser()和ImpersonateLoggedOnUser()模拟远程帐户似乎没有帮助。我知道凭据是准确的,因为我能够使用它们从远程注册表和文件系统中检索信息。
只要是程序化的,C ++,并且不涉及在远程计算机上上传和运行脚本或进程,请随意提出备用解决方案。