はじめに
UE5からTXTファイルやCSVファイルなどをテキストエディタやExcelなどのUE5外のアプリケーションで開きたいことは稀によくあります。
その際に便利な関数としてFPlatformProcess::CreateProc
や FPlatformProcess::ExecProcess
があります。
papersloth.hatenablog.com
しかし、開くファイルのパスだけでなく、開くアプリケーションのパスも指定する必要があります。たとえばExcelで開こうとした場合だとこんな感じ。
FPlatformProcess::CreateProc(TEXT(""C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE""), ...
色々面倒!パスを事前にチェックしたり、アプリがバージョンアップしてパスが変わってトラブったり、そもそもインストールされてなかったり…パスを短縮化するbatを配布しても誰も使ってくれなかったり…頭痛が痛くなりそうな状況が容易に想像できます。
そこで便利なのが今回紹介する「ファイルを拡張に関連付けられた既定アプリで開く方法」です。更に分かりやすく言うと、ファイルをダブルクリックすると自動的に確認・編集用アプリが開きますが、アレとほぼ同じことができる方法です。
この方法ならアプリのパスが不要なので、先程の懸念事項の大半をカバーできるはずです!たぶん。きっと。C++必須ですが…
ファイルを拡張に関連付けられた既定アプリで開く方法
FPlatformProcess::LaunchFileInDefaultExternalApplication
を呼び出すことで実現可能です!
例えば、プロジェクトのSavedフォルダにある hogehoge.csv を Excel で開く際は下記のように記述します。
// Savedフォルダ までの相対パスと ファイル名を結合 FString CSVRelativePath = FPaths::ProjectSavedDir() / TEXT("hogehoge.csv"); // LaunchFileInDefaultExternalApplicationはフルパスが必要なので変換 FString CsvFullPath = FPaths::ConvertRelativePathToFull(*CSVRelativePath ); // CSVファイルを既定のアプリで開く if(FPlatformProcess::LaunchFileInDefaultExternalApplication(*CsvFullPath)) { // csvファイルを開くことに成功した場合の処理 }
かんたん!!!
ちなみに、Windowsの場合では内部ではWin32 APIのShellExecuteW関数が呼ばれています。 第2引数以降はShellExecuteW関数の公式ドキュメントやブログ記事などにて使い方を確認するのが良いと思います。
bool FWindowsPlatformProcess::LaunchFileInDefaultExternalApplication( const TCHAR* FileName, const TCHAR* Parms /*= NULL*/, ELaunchVerb::Type Verb /*= ELaunchVerb::Open*/, bool bPromptToOpenOnFailure /*= true */ ) { const TCHAR* VerbString = Verb == ELaunchVerb::Edit ? TEXT("edit") : TEXT("open"); // First attempt to open the file in its default application UE_LOG(LogWindows, Log, TEXT("LaunchFileInExternalEditor %s %s"), FileName, Parms ? Parms : TEXT("") ); HINSTANCE Code = ::ShellExecuteW( NULL, VerbString, FileName, Parms ? Parms : TEXT(""), TEXT(""), SW_SHOWNORMAL ); UE_LOG(LogWindows, Log, TEXT("Launch application code for %s %s: %d"), FileName, Parms ? Parms : TEXT(""), (PTRINT)Code ); ...
LaunchFileInDefaultExternalApplication
の欠点としては、立ち上がったアプリのプロセスを直接取得することができません(ShellExecuteW
の仕様)。そのため、アプリが終了するまで処理を待つ、といったことをしたい場合はFPlatformProcess::IsApplicationRunning
という特定のプロセスが存在するか否かを確認する関数を使う必要があります。
while(FPlatformProcess::IsApplicationRunning(TEXT("EXCEL.EXE"))) { FPlatformProcess::Sleep(0.1f); }
とはいえ、サクッとファイルを外部アプリで開くには凄く便利な関数だと思います! UE5外のアプリと連携するワークフローを検討する際は是非お試しください~
おしまし