Last time, we looked at detecting packaged apps which support a particular URI scheme. Unpackaged apps do not have AppIds (in the Windows Store sense), so some of the operations don’t work.
Function | Packaged apps | Unpackaged apps |
---|---|---|
Launcher. |
Yes | No |
Launcher. |
Yes | Yes |
Launcher. |
Yes | N/A |
Launcher. |
Yes | Yes |
If you think about it, the reasons for the above entries are obvious:
Launcher.
returns a collection ofFindÂUriÂSchemeÂHandlersÂAsync AppInfo
objects, andAppInfo
objects describe packaged apps. So it has no way to report an unpackaged app.Launcher.
just tells you whether the URI can be launched or not. If it can be launched by an unpackaged app, then it will reportQueryÂUriÂSupportÂAsync( uri) Available
, just like the case where it can be launched by a packaged app. It doesn’t tell you which app will launch it, so it doesn’t run into the problem of trying to describe something that it has no way to describe.Launcher.
takes a package family name, and unpackaged apps don’t have a package family name, so it’s not even possible to specify the unpackaged app you are querying for.QueryÂUriÂSupportÂAsync( uri, pfn) Launcher.
tries to launch the URI and tells you whether it succeeded. It doesn’t tell you anything about the app that ultimately handled the URI, so unpackaged apps don’t cause any problems.LaunchÂUriÂAsync
But what if you want to ask about unpackaged apps, too?
The SHÂAssocÂEnumÂHandlersÂForÂProtocolÂByÂApplication
function gives you the apps (both packaged and unpackaged) which can launch a particular URI scheme.
Today’s smart pointer library will be (rolls dice)¹ WRL.
Microsoft::WRL::ComPtr<IEnumAssocHandlers> e; auto hr = SHAssocEnumHandlersForProtocolByApplication(L"http", IID_PPV_ARGS(&e)); if (SUCCEEDED(hr)) { Microsoft::WRL::ComPtr<IAssocHandler> handler; while (e->Next(1, &handler, nullptr) == S_OK) { PWSTR name; if (SUCCEEDED(handler->GetUIName(&name))) { printf("UI Name: %ls\n", name); CoTaskMemFree(name); } } }
You can even ask pass the URI to a specific handler by calling the Invoke
method:
HRESULT InvokeHandlerOnURI(IAssocHandler* handler, PCWSTR uri) { Microsoft::WRL::ComPtr<IShellItem> item; RETURN_IF_FAILED(SHCreateItemFromParsingName( L"http://msn.com/", nullptr, IID_PPV_ARGS(&item))); Microsoft::WRL::ComPtr<IDataObject> dto; RETURN_IF_FAILED(item->BindToHandler(nullptr, BHID_DataObject, IID_PPV_ARGS(&dto))); RETURN_IF_FAILED(handler->Invoke(dto.Get())); return S_OK; }
¹ Dirty secret: The dice are loaded.
It is interesting that WRL keeps being used by plenty of developers, despite of its deprecation, most likely because C++/WinRT hardly adds any value to the Visual Studio developer experience.
It's classic COM, WRL is just as good an option as C++/WinRT is (or _com_ptr, if you're willing to deal with some of its gotchas). C++/WinRT gives you more helpers to make life easier - I consider <code> + exception handling to be more readable than <code> - but that doesn't make it a game changer.
On the other hand, try consuming Windows Runtime classes with WRL... (And if you already might be using the Windows...
Is WRL deprecated? I know that it was superseded by C++/WinRT, but I don’t remember seeing any mention of it being deprecated.
Isn’t it also only superseded on the Windows Runtime side of things? Since the interfaces used in this post are classic COM interfaces then WRL is just as good an option.
It is, check its documentation, it is quite hard to miss the big pink square,
https://learn.microsoft.com/en-us/cpp/cppcx/wrl/windows-runtime-cpp-template-library-wrl?view=msvc-170
While it says superseded, and not deprecated, it is really the same, as it is clear where development budget is being spent.
However since, having the one true library was never a WinDev in regards to COM, not only you can use MFC, ATL, WRL, C++/CX, C++/WinRT, there is WIL as well,
https://github.com/microsoft/wil
With exception of MFC, they all share one common thread, bad...
Then no, you are incorrect on this matter.
Supersede and deprecate have completely different meanings. That big pink box states that it has been superseded and then provides reasons for why C++/WinRT should be used. It does not provide any kind of disapproval of WRL though. There is a big difference between "you shouldn't use this" and "you would find using that to be a much better experience". When Microsoft deprecate things, they don't just...