ファイルのパスを指定するとそれに関連づいたアプリで実行してくれるShellExecute関数。
そこで、そのEXEのパスを取得してみようということでいろいろやってみました。
もともと「FindExecutable」というAPIがあるのですが、いろいろ不都合があるらしいです。
こちらを参考にC形式で書いてみました。
/* WindowsXp Pro SP2 / VS 2005 Pro */ #include <windows.h> #include <locale.h> #include <tchar.h> #include <shlwapi.h> #pragma comment( lib, "shlwapi.lib" ) BOOL GetRegString( HKEY hKey, LPCTSTR lpSubKey, LPTSTR* ppValue ) { HKEY hSubKey; DWORD dwType; DWORD dwSize; LONG lResult; *ppValue = NULL; lResult = RegOpenKeyEx( hKey, lpSubKey, 0, KEY_ALL_ACCESS, &hSubKey ); if ( lResult == ERROR_SUCCESS ) { lResult = RegQueryValueEx( hSubKey, NULL, NULL, &dwType, NULL, &dwSize ); if ( ( lResult == ERROR_SUCCESS ) && ( dwType == REG_SZ ) ) { *ppValue = ( TCHAR* )malloc( dwSize ); if ( *ppValue ) { lResult = RegQueryValueEx( hSubKey, NULL, NULL, &dwType, ( LPBYTE )*ppValue, &dwSize ); } } RegCloseKey( hSubKey ); } if ( !*ppValue || ( lResult != ERROR_SUCCESS ) ) { if ( *ppValue ) { free( *ppValue ); *ppValue = NULL; } return FALSE; } return TRUE; } BOOL GetShellAppPath( LPTSTR szAppPath, const size_t nSize, LPCTSTR szFilePath ) { LPCTSTR lpExt = NULL; LPTSTR lpFileType; LPTSTR lpValue; LPTSTR lpSubKey = NULL; TCHAR szSubKeyFormat[] = TEXT( "%s\\\\shell\\\\open\\\\command" ); size_t nSubKeySize = sizeof( szSubKeyFormat ); int nRet; /* 拡張子を取得 */ lpExt = PathFindExtension( szFilePath ); if ( !lpExt ) return FALSE; /* HKEY_CLASSES_ROOT拡張子のファイルタイプ文字列を取得 */ if ( !GetRegString( HKEY_CLASSES_ROOT, lpExt, &lpFileType ) ) return FALSE; /*「アクションを実行するアプリケーション」のレジストリキー名の作成 */ nSubKeySize += _tcslen( lpFileType ) * sizeof( TCHAR ); lpSubKey = ( LPTSTR )malloc( nSubKeySize ); if ( !lpSubKey ) { free( lpFileType ); return FALSE; } nRet = _stprintf_s( lpSubKey, nSubKeySize / sizeof( TCHAR ), szSubKeyFormat, lpFileType ); free( lpFileType ); if ( nRet < 0 ) { free( lpSubKey ); return FALSE; } /*「アクションを実行するアプリケーション」のレジストリキーの値を取得 */ if ( !GetRegString( HKEY_CLASSES_ROOT, lpSubKey, &lpValue ) ) { free( lpSubKey ); return FALSE; } free( lpSubKey ); /*「アクションを実行するアプリケーション」のレジストリキーの値からパス名のみを取り出す */ if ( !PathFileExists( lpValue ) ) { PathRemoveArgs( lpValue ); PathUnquoteSpaces( lpValue ); } nRet = _tcscpy_s( szAppPath, nSize, lpValue ); free( lpValue ); return ( nRet >= 0 ) ? TRUE : FALSE; } int main( void ) { TCHAR szAppPath[ MAX_PATH ]; setlocale( LC_ALL, "" ); if ( GetShellAppPath( szAppPath, _countof( szAppPath ), TEXT( "main.cpp" ) ) ) { _tprintf( TEXT( "%s\\n" ), szAppPath ); } return 0; }