止めどない青さの行き先

日々の何気ない一言を記録したものです。

ShellExecuteで実行するEXEのパスを取得する

2006-05-29 23:59:59 | C/C++

ファイルのパスを指定するとそれに関連づいたアプリで実行してくれる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;
}


最新の画像もっと見る