System::CreateProcess()について
Mattya  2019/03/06(Wed) 10:48
Siv3D August 2016 v2を使わせてもらっています。

現在、Siv3Dを用いてランチャーを作成しています。
.exeファイルは問題なく開けるので、.htmlファイルを開きたいなと考えています。
そこで、System::CreateProcess()の挙動を少し調べるために次のようなコードを書きました。

# include <Siv3D.hpp>
# include <Windows.h>
# undef CreateProcess

void Main()
{

FilePath file = L"./test.html";
char exePath[200];

// 既定プログラムの実行パス取得
FindExecutableA(file.narrow().c_str(), "./", exePath);

System::CreateProcess(Widen(std::string(exePath)), file);

while (System::Update()) {

}

}

実行してみたところ、パスは問題なく取得できているようで、ブラウザ自体は起動するのですが、開きたいHTMLファイルが開けず、ただ新規にブラウザを起動しただけのようになってしまいます(起動時のホームページが表示される)。
コマンドプロンプト上で「ブラウザの実行パス HTMLファイル名」のようにして実行するとブラウザで開きたいHTMLファイルが開けるので、コマンドラインオプションが間違っていることは無いと思うのですが、うまく動作しない原因がわかりません(手元ではとりあえずGoogle Chromeで確かめています)。

他にも、「System::CreateProcesss(L"javawのフルパス", "-jar ./test.jar");」などとしてオプションをつけて起動するものを試してみたのですがうまく動きませんでした。なぜか「https://qiita.com/Reputeless/items/e53d0fd2672eee27754a#2-web-%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%97%E3%82%88%E3%81%86」 にあるサンプルのように「System::CreateProcess(L"C:/Program Files/Internet Explorer/iexplore.exe", L"-new http://play-siv3d.hateblo.jp/");」してみるとこれは正しく起動しました。この第二引数をローカルファイルのパスに書き換えるとうまく動きませんでした。

他にもCドライブ直下にファイルをおいてみたり、ダブルクォーテーションで括ってみたりもしましたが駄目でした。原因がわかりません。アドバイスよろしくおねがいします。
記事編集
Reputeless  2019/03/12(Tue) 09:51
調査します
編集
Reputeless  2019/03/17(Sun) 12:27
Siv3D August 2016v2 でローカルの HTML を開く場合は、次のような関数を実装してください。

# include <Siv3D.hpp>
# define NOMINMAX
# include <Windows.h>

bool OpenWithWebBrowser(const FilePath& url)
{
return reinterpret_cast<size_t>(::ShellExecuteW(nullptr, L"open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL)) > 32;
}

void Main()
{
OpenWithWebBrowser(L"test.html");

while (System::Update())
{

}
}

最初の投稿のプログラムは

# include <Siv3D.hpp>
# define NOMINMAX
# include <Windows.h>
# undef CreateProcess

void Main()
{
const FilePath filePath = L"test.html";

// Chrome のコマンド
const String command = L"-- " + FileSystem::FullPath(filePath);

// 既定プログラムの実行パス取得
wchar_t exePath[256];
::FindExecutableW(filePath.c_str(), L"./", exePath);

Println(exePath);
Println(command);

System::CreateProcess(exePath, command);

while (System::Update())
{

}
}

だとできました。
編集
Mattya  2019/03/18(Mon) 18:56
お忙しい中ありがとうございます。
なるほど、ShellExecuteWを使うのですね。勉強になりました。

実際にこれを用いて実装してみたところ、今までCreateProcess()の戻り値のProcessInfoからランチャーのMinimize()、Restore()していて、この仕様に合致させるのが難しいようでした。ただ、Reputelessさんの解答からヒントを得てShellExecuteExW()から起動してプロセスハンドルを取得し、起動中かどうか確かめる方法を試したところうまくいきました!

本当にありがとうございました!
編集
件名
Re: System::CreateProcess()について
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -