Search code examples
c#windows-10registryfile-extensionwindows-explorer

Determine all posible applications to open a file with DelegateExecute


I want to determine all posible applications to open an file with. Similar to the "Open With" context menue from the explorer.

From the Registry Key:

HKEY_CLASSES_ROOT\extension\OpenWithProgids

I can get the informations i am looking for. This part is clear to me.

But i also get an entry like "AppXea46y3k4tynme684q1dgefbnb0b9r8ec" What is "CodeWriter" a Windows store app.

If i look for this entry in the registry:

 HKEY_CLASSES_ROOT\AppXea46y3k4tynme684q1dgefbnb0b9r8ec

I found somthing like:

HKEY_CLASSES_ROOT\AppXea46y3k4tynme684q1dgefbnb0b9r8ec\Shell\open\command

For non store apps i woud finde a shell command. Like:

"%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" "%1"

From there i can determine the program (Wordpad) and everything is fine.

For the store app i find something like:

enter image description here

This DelegateExecute Value is the same for all the store apps ShellOpenCommands.

I want to know how i get from there to a usable OpenCommand. So i can determine what application it is.


Solution

  • SHAssocEnumHandlers gets the job done.

    I found a sample implementation for C++:

    #include "stdafx.h"
    #include "Shobjidl.h"
    
    int main(int argc, _TCHAR* argv[])
    {
      IEnumAssocHandlers *pEnumHandlers = NULL;
      if (SUCCEEDED(SHAssocEnumHandlers(L".bmp", ASSOC_FILTER_RECOMMENDED, &pEnumHandlers)))
      {
        IAssocHandler *pAssocHandler = NULL;
        while (S_OK == pEnumHandlers->Next(1, &pAssocHandler, NULL))
        {
          if (pAssocHandler != NULL)
          {
            LPWSTR pszName;
            LPWSTR pszUIName;
            LPWSTR ppszPath;
            int pIndex;
    
            pAssocHandler->GetUIName(&pszName);
            pAssocHandler->GetName(&pszUIName);
            pAssocHandler->GetIconLocation(&ppszPath, &pIndex);
            pAssocHandler->Release();
            pAssocHandler = NULL;
    
            printf_s("%S \n", pszUIName);
            printf_s("%S \n", pszName);
          }
        }
        pEnumHandlers->Release();
    
        scanf_s("%S");
      }
      return 0;
    }
    

    Result looks like:

    C:\Program Files (x86)\Windows Photo Viewer\PhotoViewer.dll
    Windows-Fotoanzeige
    C:\Windows\system32\mspaint.exe
    Paint

    For C# Implementation see: Use SHAssocEnumHandlers in C#