Suggestion: Support functions for COM class & TypeLib registration
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3k
- Forks
- 300
- Avg merge
- 19h 12m
- Merged PRs (30d)
- 1
Description
This suggestion was originally proposed in https://github.com/microsoft/cppwinrt/issues/1492, but the response was then to move the request to the WIL project.
BACKGROUND: I've just started modernizing some existing ATL projects to C++/WinRT. One challenge I then faced was lack of inbuilt support for registration of COM classes and type libraries. It would be very helpful if either WinRT or WIL could be extended with either support functions or sample code to demonstrate "best practice" in this area.
My "ask" is basically to add code resembling the RegisterTypeLibrary and RegisterComClass functions below to the repo.
Suggested code to add to the repo
/** COM type library (un)registration function. */
void RegisterTypeLibrary(bool do_register, std::wstring tlb_path) {
if (do_register) {
// register typelib
CComPtr<ITypeLib> tlb;
HRESULT hr = LoadTypeLibEx(tlb_path.c_str(), REGKIND_REGISTER, &tlb);
assert(SUCCEEDED(hr));
} else {
// unregister typelib
CComPtr<ITypeLib> tlb;
HRESULT hr = LoadTypeLibEx(tlb_path.c_str(), REGKIND_NONE, &tlb);
assert(SUCCEEDED(hr));
TLIBATTR* attrPtr = nullptr;
hr = tlb->GetLibAttr(&attrPtr);
assert(SUCCEEDED(hr));
UnRegisterTypeLib(attrPtr->guid, attrPtr->wMajorVerNum, attrPtr->wMinorVerNum, attrPtr->lcid, attrPtr->syskind); // will fail if already unregistered
tlb->ReleaseTLibAttr(attrPtr);
}
}
/** COM class (un)registration function. */
void RegisterComClass(bool do_register, CLSID clsid, ::GUID tlbGuid, std::wstring dll_exe_path) {
std::wstring clsid_str(38, L'\0');
int ret = StringFromGUID2(clsid, clsid_str.data(), static_cast<int>(clsid_str.size() + 1));
assert(ret == 39); ret; // includes zero-termination
if (do_register) {
// register COM class
std::wstring file_ext = dll_exe_path.substr(dll_exe_path.find_last_of(L'.'));
if (!_wcsicmp(file_ext.c_str(), L".exe")) {
std::wstring key_path = L"CLSID\\" + clsid_str + L"\\LocalServer32";
CRegKey key;
LSTATUS res = key.Create(HKEY_CLASSES_ROOT, key_path.c_str());
assert(res == ERROR_SUCCESS); res;
key.SetStringValue(nullptr, dll_exe_path.c_str());
} else if (!_wcsicmp(file_ext.c_str(), L".dll")) {
std::wstring key_path = L"CLSID\\" + clsid_str + L"\\InprocServer32";
CRegKey key;
LSTATUS res = key.Create(HKEY_CLASSES_ROOT, key_path.c_str());
assert(res == ERROR_SUCCESS); res;
key.SetStringValue(nullptr, dll_exe_path.c_str());
} else {
wprintf(L"ERROR: Unsupported file extension.\n");
abort();
}
{
std::wstring key_path = L"CLSID\\" + clsid_str + L"\\TypeLib";
CRegKey key;
LSTATUS res = key.Create(HKEY_CLASSES_ROOT, key_path.c_str());
assert(res == ERROR_SUCCESS); res;
wchar_t tlb_str[39] = {};
StringFromGUID2(tlbGuid, tlb_str, static_cast<int>(std::size(tlb_str)));
key.SetStringValue(nullptr, tlb_str);
}
} else {
// unregister COM class
CRegKey parent;
LSTATUS res = parent.Open(HKEY_CLASSES_ROOT, L"CLSID", KEY_READ | KEY_WRITE);
assert(res == ERROR_SUCCESS); res;
parent.RecurseDeleteKey(clsid_str.c_str()); // will fail if already unregistered
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed RegisterTypeLibrary and RegisterComClass functions, including their LoadTypeLibEx and registry API usage. Then inspect the WIL repository for existing patterns that could define the supported API or sample location. Done means an agreed scope and an implemented, documented approach with validation for registration and unregistration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100