C++ – Getting File Associations using Windows API

cfile-associationfile-typeregistrywindows

I'm working on a console based file browser for Windows in C++ and am having difficulties getting together a context menu that lists actions associated with a file and calls commands on them. The biggest issue right now is getting the actions tied to the file types.

I know of the process to open and tweak the registry keys in HKEY_CLASSES_ROOT but I can't find a way to actually get the actions and their commands so I can build a context menu out of it.

The general structure of these associations in the registry is:

HKEY_CLASSES_ROOT\(extension)\(default) – filetype
HKEY_CLASSES_ROOT\filetype\(default) – description of the filetype
HKEY_CLASSES_ROOT\filetype\shell\action\(default) – description of the action
HKEY_CLASSES_ROOT\filetype\shell\action\command\(default) – command called on file

I'm wondering if there is a way (hopefully using the Windows API) that I can get all of the actions associated with a file type. At least then I can check those actions for their commands in the registry…

Also, this approach doesn't seem to work with some common file types (e.g. mp3) on my system as the default key is left blank and another key ("PercievedType") is set to audio… How can I get the actions for something like this?

Lastly, if there is a better way to do this in general I would love to hear it, I generally hate dealing with the registry. I would much rather have a simple windows call that would get me the actions and commands…

Best Answer

Try this (error handling omitted for brevity):

TCHAR szBuf[1000];
DWORD cbBufSize = sizeof(szBuf);
HRESULT hr = AssocQueryString(0, ASSOCSTR_FRIENDLYAPPNAME,
   argv[1], NULL, szBuf, &cbBufSize);
if (FAILED(hr)) { /* handle error */ }
CStringA strFriendlyProgramName(szBuf, cbBufSize);

cbBufSize = sizeof(szBuf);
hr = AssocQueryString(0, ASSOCSTR_EXECUTABLE, 
   argv[1], NULL, szBuf, &cbBufSize);
if (FAILED(hr)) { /* handle error */ }
CStringA strExe(szBuf, cbBufSize);

std::cout << strFriendlyProgramName << " (" << strExe << ")" << std::endl;