スポンサーリンク
AssocQueryStringWを使ってファイルの拡張子または存在するファイルから関連付けられたアプリケーションを特定できる。
#include <iostream> #include <windows.h> #include <shlwapi.h> #include <string> #include <vector> #pragma comment(lib, "shlwapi.lib")
std::wstring CallAssocQueryString(const std::wstring& filepath, ASSOCSTR str) { DWORD len = 0; // まずは、必要なバッファサイズを取得 // lenにはnull終端を含む文字列の長さが返される HRESULT hr = AssocQueryStringW( ASSOCF_NONE, str, filepath.c_str(), // 拡張子".txt"等、 または存在するファイルパス nullptr, nullptr,// 結果を格納するバッファを指定するが、先にサイズを取得するためnullptrを指定 &len // 結果を格納するのに必要なバッファサイズを取得 ); if (hr != S_OK && hr != S_FALSE) { std::wcerr << L"AssocQueryStringW failed with error: " << hr << std::endl; return L""; } // バッファサイズがわかったので、結果を格納するバッファを確保 std::vector<wchar_t> appPath(len , L'\0'); hr = AssocQueryStringW( ASSOCF_NONE, str, filepath.c_str(), nullptr, &appPath[0], &len ); return std::wstring(appPath.data()); }
int main() { std::wstring target = L".sln"; // 拡張子から関連付けられたアプリケーションのパスを取得 std::wstring appPath = CallAssocQueryString(target, ASSOCSTR_EXECUTABLE); std::wcout << appPath << std::endl; // 関連付けられたアプリケーションの表示名を取得。 // ただし登録されていない場合も多いので、必ずしも取得できるとは限らない。 std::wstring appName = CallAssocQueryString(target, ASSOCSTR_FRIENDLYAPPNAME); std::wcout << appName << std::endl; // 関連付けられたアプリケーションの実行コマンドを取得 std::wstring appCommand = CallAssocQueryString(target, ASSOCSTR_COMMAND); std::wcout << appCommand << std::endl; return 0; }
windowsではアプリケーションの第一引数にファイルを与えるのが一般的らしいのでASSOCSTR_EXECUTABLEで取得した アプリケーションのパス + ファイルパスでもいいが、より確実にはASSOCSTR_COMMANDで取得した実行コマンドの %1 の部分をファイルパスに置換した方が確実。
#include <iostream> #include <windows.h> #include <shlwapi.h> #include <string> #include <vector> #include <regex> #pragma comment(lib, "shlwapi.lib")
std::wstring CallAssocQueryString(const std::wstring& filepath, ASSOCSTR str) { DWORD len = 0; // まずは、必要なバッファサイズを取得 // lenにはnull終端を含む文字列の長さが返される HRESULT hr = AssocQueryStringW( ASSOCF_NONE, str, filepath.c_str(), // 拡張子".txt"等、 または存在するファイルパス nullptr, nullptr,// 結果を格納するバッファを指定するが、先にサイズを取得するためnullptrを指定 &len // 結果を格納するのに必要なバッファサイズを取得 ); if (hr != S_OK && hr != S_FALSE) { std::wcerr << L"AssocQueryStringW failed with error: " << hr << std::endl; return L""; } // バッファサイズがわかったので、結果を格納するバッファを確保 std::vector<wchar_t> appPath(len , L'\0'); hr = AssocQueryStringW( ASSOCF_NONE, str, filepath.c_str(), nullptr, &appPath[0], &len ); return std::wstring(appPath.data()); }
int main() { std::wstring target = LR"(C:\test\test.txt)"; // 関連付けられたアプリケーションの実行コマンドを取得 std::wstring appCommand = CallAssocQueryString(target, ASSOCSTR_COMMAND); std::wcout << appCommand << std::endl; // appCommandは、"C:\Path\To\App.exe" "%1" のような形式 // "%1"をファイルパスに置き換えるとApp.exeでファイルを開ける std::wregex percent1_pattern(LR"((\"?)%1(\"?))"); // %1 または "%1" にマッチ std::wstring quoted_path = L"\"" + target + L"\""; std::wstring command = std::regex_replace(appCommand, percent1_pattern, quoted_path); std::wcout << "Command: " << command << std::endl; STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi; BOOL ret = CreateProcessW( nullptr, &command[0], // 開きたいファイルを含むコマンド nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &si, &pi ); return 0; }