エクスプローラーでファイルをダブルクリックしたときに使われる実行ファイルを取得するには
AssocQueryStringを利用する。ただし取得結果は必ずしもexeファイルになるとは限らない。拡張子によってはdllファイルなどに関連づいていることもある。(例:jpegファイルでshimgvw.dllが取得されるなど)
#include "atlstr.h"
#include "shlwapi.h"
#pragma comment(lib,"shlwapi.lib")
//
// 拡張子に関連付けられた実行ファイル取得
//
// pszExtensionは".txt"のようにする("txt"でも構わない)
// ".bat"を取得すると"%1"になるなど実際のコマンドとならないことがある!
// 拡張子によってはdllファイル名が返ることがある!
//
bool GetExecutable(LPCTSTR pszExtension,CAtlString* pstrCommand)
{
DWORD dwOut;
HRESULT hr;
TCHAR pszFile[MAX_PATH*2];
CAtlString strExt;
if(pstrCommand == NULL)
return false;
*pstrCommand = _T("");
if(pszExtension == NULL)
return false;
strExt = pszExtension;
if(strExt.Left(1) != _T("."))
strExt = _T(".") + strExt;
if(strExt.GetLength() == 1)
return false;
//pszFileの代わりにNULLを渡せば必要なバッファーが取得できるはずだが...うまく動かない
//ことがあるのでMAX_MAX*2の固定長で文字列を取得している
dwOut = MAX_PATH*2;
hr = ::AssocQueryString(ASSOCF_NOTRUNCATE,ASSOCSTR_EXECUTABLE,strExt,_T("open"),pszFile,&dwOut);
if(FAILED(hr) || dwOut == 0)
return false;
*pstrCommand = pszFile;
return true;
}
void Test(void)
{
bool ret;
CAtlString strCommand;
ret = GetExecutable(_T(".jpg"),&strCommand);
if(ret)
::MessageBox(NULL,strCommand,_T(""),MB_OK);
else
::MessageBox(NULL,_T("取得に失敗しました"),_T(""),MB_OK);
}
