Enumerating all the programs that can launch a particular protocol


Today's Little Program is a variation on the one from last time. This time, instead of enumerating all the handlers for a file extension, we enumerate all the handlers for a protocol. We then open a Web site with that chosen program.

Start with the program from last time and make these changes:

std::vector<CComPtr<IAssocHandler>> LoadHandlers(
  PCWSTR extension)
  // ASSOC_FILTER filter
  )
{
  std::vector<CComPtr<IAssocHandler>> handlers;
  CComPtr<IEnumAssocHandlers> enumerator;
  SHAssocEnumHandlersForProtocolByApplication(
    L"http", IID_PPV_ARGS(&enumerator));
  for (CComPtr<IAssocHandler> handler;
       enumerator->Next(1, &handler, nullptr) == S_OK;
       handler.Release()) {
       handlers.push_back(handler);
  }
  return handlers;
}

The SHAssoc­Enum­Handlers­ForProtocol­By­Application function does not have a filter option, so we delete that parameter from Load­Handlers.

The Choose­Handler function is unchanged.

int __cdecl main(int, char**)
{
  CCoInitialize init;
  ProcessReference ref;

  auto handlers = LoadHandlers(L"http");
  auto selection = ChooseHandler(handlers, false);

  if (selection < handlers.size()) {
    CComPtr<IDataObject> dobj;
    GetUIObjectOfFile(nullptr, L"http://www.microsoft.com/",
                      IID_PPV_ARGS(&dobj));
    handlers[selection]->Invoke(dobj);
  }
  return 0;
}

This version is shorter because there is no filter option, so we just load up all the handlers, pick one, and invoke it.

Notice that we are using Get­UI­Object­Of­File for something that isn't a file. If you go back to that function, you'll see that there's nothing in it that actually requires a file. It can accept any parseable name. A more accurate name for the function would have been Get­UI­Object­Of­Parsing­Name, but it's too late now.

Comments (22)
  1. skSdnW says:

    How far back does Urls in Pidls support go? I'm assuming not Win95?

  2. Mark says:

    You forgot to use 'extension' in the call to SHAssocEnumHandlersForProtocolByApplication.

  3. Joshua says:

    I'll bet it does to back to Win95 because the function doesn't really check that well.

  4. skSdnW says:

    After replacing SHParseDisplayName and SHBindToParent with custom versions it failed to parse URLs on Win95 and NT5SP6 with 0x80004005 but worked on 98, 98SE, ME, 2000 and XP. It might be possible to parse a URL with something other than the IShellFolder you get from SHGetDesktopFolder but I don't remember the details anymore. Maybe Raymond does?

  5. Nick says:

    @skSdnW: I'm betting it was added in the desktop extensions with IE 4 then.

  6. skSdnW says:

    @Nick: Yes the root IShellFolder probably gained the ability to parse URLs in the IE4 shell update but I believe it was possible to put a URL in a pidl before this as well. I think it had something to do with CSIDL_INTERNET but I just don't remember the details.

  7. cheong00 says:

    Off topic: Seems the new blog site needs multiple redirect to login, this is annoying. (The same goes to the old Microsoft Partner Network site, although I think that one is excusible because they need to support ADFS login. The new site can allow me to just click "Sign in" to login now so hopefully this site can do that too in short time)

  8. Felipe Pereira says:

    just, what happened with this blog layout?

  9. Kevin says:

    Well, since no one else has brought it up yet, I'll bite.

    Raymond, your site looks different!

    There. Now that we have the perfectly obvious statement out of the way, we can get back to more interesting fare.

  10. Wow! This blogs looks so pretty! No more pressing Ctrl+Ins every time I come here...

    I hope this redecoration is permanent.

    1. Neil says:

      Unfortunately all of the old links, such as the "I wrote a book" link, are broken. (This also confused my feed reader.) Also the cover image itself is still http: which annoys my browser.
      But at least the Post Comment button is accessible again.

      1. cheong00 says:

        Raymond can change the URL's to prefix with http://blogs.msdn.com/b instead and it'll automatically redirected to the corresponding URL in new site. (e.g.: http://blogs.msdn.com/b/oldnewthing/archive/2006/12/07/1233002.aspx )

        1. Neil says:

          It seems he's done that now, as I tried an old-style link and it worked.

  11. My Eyes! says:

    Argh! Change it back!

  12. Boris says:

    I disagree; now the blog looks more getwiththeprogram than oldnew. The whole point of oldnewthing is that some things stay the same even as the world around them is affected by all kinds of "disruptive" ideas; how better to express that than with a custom blog theme which merely evolves with the times, without any radical changes on the surface? I actually thought my browser was having problems displaying the usual theme, so it went with a simplified version instead.

  13. Brian_EE says:

    @Fleet Command - I disagree. For one, the light yellow stars are very hard to see against an all white background, and I have good vision. Doesn't seem like it's a good color scheme from an accessibility standpoint.

  14. To participate in the off-topic topic, I don't mind the new look, and I'm sure I'll get used to it if it is a permanent change. I do dislike the change initially though, for two reasons. First, because I'm on the internet and it's change, and that's all that needs to be said. Second, because it makes the blog look like Yet Another MSDN Blog. The old one had a character of it's own.

    Also, I dislike the new email requirement for posting comments. Here's hoping it's easy to fake out.

  15. mikeb says:

    The change in the blog template is a definite step backwards in readability.

  16. Scarlet Manuka says:

    The new layout does seem to make some formats less easily visible in the posts, but overall it's not too bad, and I'm sure I'll get used to it with time.

    It does seem to have broken links to comments though. Links to posts seem to redirect OK but the links to comments just go to the associated post again. Oh well, it was nice to have them working while they lasted.

    (Currently on an archive kick from home. Having the archives broken up by year only instead of by month is also a little awkward, but it's a minor issue.)

    1. It looks like you can use https://blogs.msdn.microsoft.com/oldnewthing/yyyy/mm to generate a monthly archive for any month.

  17. I haven't done anything. That's all server-side stuff that I don't control.

  18. Medinoc says:

    "Notice that we are using Get­UI­Object­Of­File for something that isn’t a file. If you go back to that function, you’ll see that there’s nothing in it that actually requires a file. It can accept any parseable name. A more accurate name for the function would have been Get­UI­Object­Of­Parsing­Name, but it’s too late now. "
    Doesn't IShellFolder::GetUIObjectOf() call IPersistFile::Load()? What happens if Load() fails?

    PS: I can no longer comment with my Microsoft Account, it still whines that the Name and Email fields are empty.

Comments are closed.

Skip to main content