hozugawa.net · A neutral informational page

ShellExecuteでファイルやURLを開く

Windows的文件やフォルダ、ウェブページを開く操作は、シェルが管理するファイル関連付けやプロトコルハンドラーへ委譲できます。ShellExecuteは、対象と実行する操作を指定して、既定のアプリケーションを起動するAPIです。

起動するアプリケーションのパスを固定せず、拡張子やhttpスキームに応じた既定動作を利用できる点が特徴です。ただし、関連付けやユーザー設定によって起動先が変わり、起動要求の成功と対象処理の完了は区別する必要があります。

関数の役割と成功判定

戻り値の型はHINSTANCEですが、後続の処理でハンドルとして使うためのものではありません。成功値は32より大きく、失敗値は32以下です。失敗コードには、ファイルが見つからないSE_ERR_FNFや関連付けがないSE_ERR_NOASSOCなどがあります。

失敗コードだけでは原因を詳しく判別できません。また、ShellExecute失敗後にGetLastErrorを呼んでも、安定したエラー情報を得られるとは限りません。

観点 ShellExecute ShellExecuteEx
呼び出し形式 関数の引数で指定 SHELLEXECUTEINFO構造体で指定
成功判定 戻り値が32より大きい TRUEが返る
失敗時の情報 失敗コードの範囲は限定的 FALSEの直後にGetLastErrorを確認できる
プロセス プロセスハンドルを取得できない SEE_MASK_NOCLOSEPROCESSで取得できる
エラー表示 標準のシェル動作に従う SEE_MASK_FLAG_NO_UIで関数自身_customize抑制できる

詳細な診断やプロセス管理が必要ならShellExecuteExを使います。SHELLEXECUTEINFOを初期化し、fMaskへSEE_MASK_NOCLOSEPROCESSを指定すると、起動したプロセスのハンドルを取得できます。

Unicode版を使った呼び出し

文字コードに依存しない実装にはShellExecuteWを使います。UNICODEが定義されたヘッダーでは、ShellExecuteマクロもShellExecuteWに展開されます。

#include <windows.h>
#include <shellapi.h>
#include <cstdint>

HINSTANCE result = ShellExecuteW(
    nullptr,                            // 親ウィンドウ
    L"open",                            // 実行する操作
    L"C:\\Users\\Public\\sample.pdf",   // 開く対象
    nullptr,                            // 追加の引数
    nullptr,                            // 作業ディレクトリ
    SW_SHOWNORMAL                       // 表示方法
);

if (reinterpret_cast<std::intptr_t>(result) <= 32) {
    // 起動失敗を処理する
}

各引数は、親ウィンドウ、実行する操作、対象、追加引数、作業ディレクトリ、表示方法を表します。lpParametersの引用符や空白は、実行側の引数解析に合わせて適切に処理します。lpDirectoryは起動プロセスの作業ディレクトリであり、呼び出し元プロセスのカレントディレクトリは変更しません。

呼び出し成功は、表示や編集が終わったことを意味しません。プロセス終了まで待つ必要がある場面では、ShellExecuteExで取得したハンドルを使い、WaitForSingleObjectで待機してからCloseHandleで解放します。

文字列とパスを安全に扱う

日本語を含むパスを扱うなら、文字列型を明示したShellExecuteWが基本です。ファイル名の文字コードと、関連付け先のアプリケーションが受け取る文字コードは別問題なので、後者まで同一と仮定しないことが重要です。

httpやhttpsなどのURLは、プロトコルハンドラーへ渡されます。通常はブラウザーが開きますが、ユーザーが別の既定アプリを変更している場合があります。特定の実行ファイルへ固定依靠せず、関連付けの委譲機構を利用するのがこのAPIの役割です。

実行操作と権限の制御

lpOperationにはopenやexploreなどの実行操作を指定します。関連付け deed разрешен動詞や権限昇格動詞には、用途に応じた制限が必要です。

権限昇格を使う場面では、要求がユーザーに明示されているかを確認します。仕様に迷った際は、API仕様の参考先も利用できます。

実務で押さえる基準

単純な既定動作の起動ならShellExecuteで十分です。失敗原因の収集やプロセス待機まで行う場合は、ShellExecuteExとSHELLEXECUTEINFOが適します。

文字列入力を扱う実装ではShellExecuteWを選び、権限昇格や入力検証を省略しないことも確認します。ShellExecuteは関連付け処理の委譲と起動要求を担うAPIです。関連付けに委譲すること、32を超えた戻り値だけを成功とすること、処理の完了は別に確認することを覚えておいてください。