From a Windows app, how can I check whether there is an app installed that implements a particular URI scheme?, part 2
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 ofFindUriSchemeHandlersAsync 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 reportQueryUriSupportAsync( 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.QueryUriSupportAsync( 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.LaunchUriAsync
But what if you want to ask about unpackaged apps, too?
The SHAssocEnumHandlersForProtocolByApplication
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.
4 comments
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.
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 developer experience for COM authoring and lack of Visual Studio tooling for IDL files, maybe that is where budget could be spent, instead of replacing C++ frameworks for COM every couple of years.
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 have it in the documentation in one little pink box that states Note, they make it really obvious. For example:
Advocating for better development tooling is one thing. Using this post in the way you did was completely off of the mark.