From 9f80486fb0d324ec16643beb78487f56d4905683 Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 7 Feb 2021 23:17:11 +0900 Subject: [PATCH 1/4] =?UTF-8?q?winmaintest=E3=82=92=E3=83=91=E3=83=A9?= =?UTF-8?q?=E3=83=A1=E3=83=BC=E3=82=BF=E3=83=86=E3=82=B9=E3=83=88=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unittests/test-winmain.cpp | 59 +++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/tests/unittests/test-winmain.cpp b/tests/unittests/test-winmain.cpp index f4279c1956..e87e32befe 100644 --- a/tests/unittests/test-winmain.cpp +++ b/tests/unittests/test-winmain.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "config/maxdata.h" @@ -48,6 +49,8 @@ #include "env/DLLSHAREDATA.h" #include "util/file.h" #include "config/system_constants.h" +#include "_main/CCommandLine.h" +#include "_main/CControlProcess.h" #include "StartEditorProcessForTest.h" @@ -74,7 +77,7 @@ typedef std::unique_ptr::type, handle_closer> handle * 始動前に設定ファイルを削除するようにしている。 * テスト実行後に設定ファイルを残しておく意味はないので終了後も削除している。 */ -class WinMainTest : public ::testing::Test { +class WinMainTest : public ::testing::TestWithParam { protected: /*! * 設定ファイルのパス @@ -87,13 +90,27 @@ class WinMainTest : public ::testing::Test { * テストが起動される直前に毎回呼ばれる関数 */ void SetUp() override { + // テスト用プロファイル名 + const std::wstring_view profileName(GetParam()); + + // コマンドラインのグローバル変数をセットする + auto &commandLine = *CCommandLine::getInstance(); + const auto strCommandLine = strprintf(LR"(-PROF="%s")", profileName.data()); + commandLine.ParseCommandLine(strCommandLine.data(), false); + + // プロセスのインスタンスを用意する + CControlProcess dummy(nullptr, strCommandLine.data()); + // INIファイルのパスを取得 iniPath = GetIniFileName(); - if( fexist( iniPath.c_str() ) ){ - // INIファイルを削除する - std::filesystem::remove( iniPath ); + // INIファイルを削除する + if (fexist(iniPath.c_str())) { + std::filesystem::remove(iniPath); } + + // コマンドラインのグローバル変数を元に戻す + commandLine.ParseCommandLine(L"", false); } /*! @@ -101,7 +118,14 @@ class WinMainTest : public ::testing::Test { */ void TearDown() override { // INIファイルを削除する - std::filesystem::remove( iniPath ); + if (fexist(iniPath.c_str())) { + std::filesystem::remove(iniPath); + } + + // プロファイル指定がある場合、フォルダも削除しておく + if (const std::wstring_view profileName(GetParam()); profileName.length() > 0) { + std::filesystem::remove(iniPath.parent_path()); + } } }; @@ -234,10 +258,10 @@ void CControlProcess_Terminate( LPCWSTR lpszProfileName ) * プログラムが起動する正常ルートに潜む障害を検出するためのもの。 * コントロールプロセスを実行する。 */ -TEST_F( WinMainTest, runWithNoWin ) +TEST_P(WinMainTest, runWithNoWin) { // テスト用プロファイル名 - constexpr auto szProfileName = L""; + const auto szProfileName(GetParam()); // コントロールプロセスを起動する CControlProcess_Start( szProfileName ); @@ -254,16 +278,19 @@ TEST_F( WinMainTest, runWithNoWin ) * プログラムが起動する正常ルートに潜む障害を検出するためのもの。 * エディタプロセスを実行する。 */ -TEST_F( WinMainTest, runEditorProcess ) +TEST_P(WinMainTest, runEditorProcess) { + // テスト用プロファイル名 + const auto szProfileName(GetParam()); + // エディタプロセスを起動するため、テスト実行はプロセスごと分離して行う - auto separatedTestProc = [] { + auto separatedTestProc = [szProfileName]() { std::mutex mtx; std::condition_variable cv; bool initialized = false; // エディタプロセスが起動したコントロールプロセスの終了を待機するスレッド - auto waitingThread = std::thread([&mtx, &cv, &initialized] { + auto waitingThread = std::thread([&mtx, &cv, &initialized, szProfileName] { // 初期化 { std::unique_lock lock( mtx ); @@ -271,9 +298,6 @@ TEST_F( WinMainTest, runEditorProcess ) cv.notify_one(); } - // テスト用プロファイル名 - constexpr auto szProfileName = L""; - // コントロールプロセスの初期化完了を待つ CControlProcess_WaitForInitialized( szProfileName ); @@ -342,3 +366,12 @@ TEST_F( WinMainTest, runEditorProcess ) // コントロールプロセスが終了すると、INIファイルが作成される ASSERT_TRUE( fexist( iniPath.c_str() ) ); } + +/*! + * @brief パラメータテストをインスタンス化する + * プロファイル指定なしとプロファイル指定ありの2パターンで実体化させる + */ +INSTANTIATE_TEST_CASE_P(ParameterizedTestWinMain + , WinMainTest + , ::testing::Values(L"", L"profile1") +); From 053fcc211e3562f44b0771c1e7c7f7e5c25ff726 Mon Sep 17 00:00:00 2001 From: berryzplus Date: Mon, 8 Feb 2021 00:17:53 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=83=88=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=83=97=E3=83=AD=E3=82=BB=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E4=BA=8C?= =?UTF-8?q?=E9=87=8D=E5=8C=96=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unittests/test-winmain.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/unittests/test-winmain.cpp b/tests/unittests/test-winmain.cpp index e87e32befe..21524a3b52 100644 --- a/tests/unittests/test-winmain.cpp +++ b/tests/unittests/test-winmain.cpp @@ -253,24 +253,40 @@ void CControlProcess_Terminate( LPCWSTR lpszProfileName ) } } +/*! + * @brief コントロールプロセスを起動し、終了指示を出して、終了を待つ + */ +void CControlProcess_StartAndTerminate(std::wstring_view profileName) +{ + // コントロールプロセスを起動する + CControlProcess_Start(profileName.data()); + + // コントロールプロセスに終了指示を出して終了を待つ + CControlProcess_Terminate(profileName.data()); +} + /*! * @brief wWinMainを起動してみるテスト * プログラムが起動する正常ルートに潜む障害を検出するためのもの。 * コントロールプロセスを実行する。 + * プロセス起動は2回行い、1回目でINI作成&書き込み、2回目でINI読み取りを検証する。 */ TEST_P(WinMainTest, runWithNoWin) { // テスト用プロファイル名 const auto szProfileName(GetParam()); - // コントロールプロセスを起動する - CControlProcess_Start( szProfileName ); + // コントロールプロセスを起動し、終了指示を出して、終了を待つ + CControlProcess_StartAndTerminate(szProfileName); - // コントロールプロセスに終了指示を出して終了を待つ - CControlProcess_Terminate( szProfileName ); + // コントロールプロセスが終了すると、INIファイルが作成される + ASSERT_TRUE(fexist(iniPath.c_str())); + + // コントロールプロセスを起動し、終了指示を出して、終了を待つ + CControlProcess_StartAndTerminate(szProfileName); // コントロールプロセスが終了すると、INIファイルが作成される - ASSERT_TRUE( fexist( iniPath.c_str() ) ); + ASSERT_TRUE(fexist(iniPath.c_str())); } /*! From 4f7087e1045aa0e1a6396d79bdd8881105221587 Mon Sep 17 00:00:00 2001 From: berryzplus Date: Thu, 11 Feb 2021 15:46:54 +0900 Subject: [PATCH 3/4] =?UTF-8?q?runEditorProcess=E3=81=AE=E5=AE=9F=E6=96=BD?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unittests/StartEditorProcessForTest.h | 9 +-- tests/unittests/code-main.cpp | 65 ++++++++------------- tests/unittests/test-winmain.cpp | 56 +++++------------- 3 files changed, 40 insertions(+), 90 deletions(-) diff --git a/tests/unittests/StartEditorProcessForTest.h b/tests/unittests/StartEditorProcessForTest.h index 23d532b5b3..16c84c9472 100644 --- a/tests/unittests/StartEditorProcessForTest.h +++ b/tests/unittests/StartEditorProcessForTest.h @@ -24,13 +24,6 @@ */ #pragma once -#ifndef NOMINMAX -#define NOMINMAX -#endif /* #ifndef NOMINMAX */ - -#include -#include - #include /*! @@ -45,4 +38,4 @@ * googletestでは、ASSERT_EXITで起動したプロセスの完全な終了を待機できないようです。 * コントロールプロセスが終了する前に他のテストが実行されると期待した動作にならない場合があります。 */ -int StartEditorProcessForTest( const std::wstring_view& strCommandLine ); +int StartEditorProcessForTest(std::wstring_view commandLine); diff --git a/tests/unittests/code-main.cpp b/tests/unittests/code-main.cpp index cf801bdac7..f67ebaad56 100644 --- a/tests/unittests/code-main.cpp +++ b/tests/unittests/code-main.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include "debug/Debug2.h" #include "StartEditorProcessForTest.h" @@ -44,25 +45,31 @@ * テストコード専用wWinMain呼出のラッパー関数 * * 単体テストから wWinMain を呼び出すためのラッパー関数です。 - * - * コマンドラインでプロファイルが指定されていない場合、空指定を付加します。 + * コマンドラインには -PROF 指定が含まれている必要があります。 */ -int StartEditorProcessForTest( const std::wstring_view& strCommandLine ) +int StartEditorProcessForTest(std::wstring_view commandLine) { - // 実行中モジュールのインスタンスハンドルを取得する - HINSTANCE hInstance = ::GetModuleHandle( NULL ); + HINSTANCE hInstance = ::GetModuleHandleW(nullptr); - // WinMainを起動するためのコマンドラインを組み立てる - std::wstring strCmdBuff( strCommandLine ); + // WinMainに渡すためのコマンドライン + std::wstring strCommandLine(commandLine); - // コマンドラインに -PROF 指定がない場合は付加する - if( !std::regex_search( strCmdBuff, std::wregex( L"-PROF\\b", std::wregex::icase ) ) ){ - strCmdBuff += L" -PROF=\"\""; + // コマンドラインに -PROF 指定がない場合は例外を投げて異常終了させる + if (!std::regex_search(strCommandLine, std::wregex(LR"(-PROF\b)", std::wregex::icase))) { + throw std::runtime_error("profileName is missing.."); } + // ログ出力 + printf("%s(%d): launching process [%ls]\n", __FILE__, __LINE__, strCommandLine.c_str()); + // wWinMainを起動する - return wWinMain( hInstance, NULL, &*strCmdBuff.begin(), SW_SHOWDEFAULT ); + const int ret = wWinMain(hInstance, nullptr, strCommandLine.data(), SW_SHOWDEFAULT); + + // ログ出力(途中でexitした場合は出力されない) + printf("%s(%d): leaving process [%ls] => %d\n", __FILE__, __LINE__, strCommandLine.c_str(), ret); + + return ret; } /*! @@ -71,47 +78,23 @@ int StartEditorProcessForTest( const std::wstring_view& strCommandLine ) * コマンドラインに -PROF 指定がない場合、呼出元に制御を返す。 * コマンドラインに -PROF 指定がある場合、wWinMainを呼出してプログラムを終了する。 */ -static void InvokeWinMainIfNeeded( char** ppArgsBegin, char** ppArgsEnd ) +static void InvokeWinMainIfNeeded(std::wstring_view commandLine) { // コマンドライン引数がない場合 - if( ppArgsBegin == ppArgsEnd ){ + if (commandLine.empty()) { return; } // コマンドラインに -PROF 指定がない場合 - if( ppArgsEnd == std::find_if( ppArgsBegin, ppArgsEnd, []( const char* arg ){ return std::regex_search( arg, std::regex( "-PROF\\b", std::regex::icase ) ); } ) ){ + if (!std::regex_search(commandLine.data(), std::wregex(LR"(-PROF\b)", std::wregex::icase))) { return; } - // 最初の引数はプログラム名なので無視する - ppArgsBegin++; - - // wWinMainを起動するためのコマンドラインを組み立てる(バッファ長はざっくり定義。) - wchar_t szCmdBuf[4096]; - std::wstring strCommandLine; - std::for_each( ppArgsBegin, ppArgsEnd, [&strCommandLine, &szCmdBuf]( const auto* arg ){ - ::swprintf_s( szCmdBuf, L"%hs ", arg ); - strCommandLine += szCmdBuf; - } ); - - // 末尾の空白を削る(引数0個はここに来ないのでチェックしない) - strCommandLine.assign( strCommandLine.data(), strCommandLine.length() - 1 ); - - // 実行中モジュールのインスタンスハンドルを取得する - HINSTANCE hInstance = ::GetModuleHandleW( NULL ); - - // ログ出力 - WCHAR *pszCommandLine = &*strCommandLine.begin(); - printf( "%s(%d): launching process [%ls]\n", __FILE__, __LINE__, pszCommandLine ); - // wWinMainを起動する - int ret = wWinMain( hInstance, NULL, pszCommandLine, SW_SHOWDEFAULT ); - - // ログ出力(途中でexitした場合は出力されない) - printf( "%s(%d): leaving process [%ls] => %d\n", __FILE__, __LINE__, pszCommandLine, ret ); + const int ret = StartEditorProcessForTest(commandLine); // プログラムを終了する(呼出元に制御は返らない) - exit( ret ); + exit(ret); } /*! @@ -119,7 +102,7 @@ static void InvokeWinMainIfNeeded( char** ppArgsBegin, char** ppArgsEnd ) */ int main(int argc, char **argv) { // コマンドラインに -PROF 指定がある場合、wWinMainを起動して終了する。 - InvokeWinMainIfNeeded( argv, argv + argc ); + InvokeWinMainIfNeeded(::GetCommandLineW()); // WinMainを起動しない場合、標準のgtest_main同様の処理を実行する printf("Running main() from %s\n", __FILE__); diff --git a/tests/unittests/test-winmain.cpp b/tests/unittests/test-winmain.cpp index 21524a3b52..d25af7623d 100644 --- a/tests/unittests/test-winmain.cpp +++ b/tests/unittests/test-winmain.cpp @@ -212,16 +212,17 @@ void CControlProcess_Start( LPCWSTR lpszProfileName ) * CControlProcess::Terminateとして実装したいコードです。本体を変えたくないので一時定義しました。 * 既存コードに該当する処理はありません。 */ -void CControlProcess_Terminate( LPCWSTR lpszProfileName ) +void CControlProcess_Terminate(std::wstring_view profileName) { // トレイウインドウを検索する std::wstring strCEditAppName( GSTR_CEDITAPP ); - if( lpszProfileName && lpszProfileName[0] ){ - strCEditAppName += lpszProfileName; + if (profileName.length() > 0) { + strCEditAppName += profileName; } HWND hTrayWnd = ::FindWindow( strCEditAppName.data(), strCEditAppName.data() ); if( !hTrayWnd ){ - throw std::runtime_error( "tray window is not found." ); + // ウインドウがなければそのまま抜ける + return; } // トレイウインドウからプロセスIDを取得する @@ -301,33 +302,6 @@ TEST_P(WinMainTest, runEditorProcess) // エディタプロセスを起動するため、テスト実行はプロセスごと分離して行う auto separatedTestProc = [szProfileName]() { - std::mutex mtx; - std::condition_variable cv; - bool initialized = false; - - // エディタプロセスが起動したコントロールプロセスの終了を待機するスレッド - auto waitingThread = std::thread([&mtx, &cv, &initialized, szProfileName] { - // 初期化 - { - std::unique_lock lock( mtx ); - initialized = true; - cv.notify_one(); - } - - // コントロールプロセスの初期化完了を待つ - CControlProcess_WaitForInitialized( szProfileName ); - - // 起動時実行マクロが全部実行し終わるのを待つ - ::Sleep( 10000 ); - - // コントロールプロセスに終了指示を出して終了を待つ - CControlProcess_Terminate( szProfileName ); - }); - - // スレッドの初期化完了を待機する - std::unique_lock lock( mtx ); - cv.wait(lock, [&initialized] { return initialized; }); - // 起動時実行マクロの中身を作る std::wstring strStartupMacro; strStartupMacro += L"Down();"; @@ -360,24 +334,24 @@ TEST_P(WinMainTest, runEditorProcess) strStartupMacro += L"SetFontSize(0, -1, 2);"; // 相対指定 - これ以上縮小できない strStartupMacro += L"SetFontSize(100, 0, 2);"; // 元に戻す // フォントサイズ設定のテスト(ここまで) + strStartupMacro += L"ExitAll();"; //NOTE: このコマンドにより、エディタプロセスは起動された直後に終了する。 // コマンドラインを組み立てる - std::wstring strCommandLine( _T(__FILE__) L" -MTYPE=js" ); - strCommandLine += L" -M=\""s; - strCommandLine += std::regex_replace( strStartupMacro, std::wregex( L"\"" ), L"\"\"" ); - strCommandLine += L"\""s; + std::wstring strCommandLine(_T(__FILE__)); + strCommandLine += strprintf(LR"( -PROF="%s")", szProfileName); + strCommandLine += strprintf(LR"( -MTYPE=js -M="%s")", std::regex_replace( strStartupMacro, std::wregex( L"\"" ), L"\"\"" ).c_str()); // エディタプロセスを起動する - StartEditorProcessForTest( strCommandLine ); + const int ret = StartEditorProcessForTest(strCommandLine); - // エディタ終了を待機する - if( waitingThread.joinable() ){ - waitingThread.join(); - } + exit(ret); }; // テストプログラム内のグローバル変数を汚さないために、別プロセスで起動させる - ASSERT_EXIT({ separatedTestProc(); exit(0); }, ::testing::ExitedWithCode(0), ".*" ); + ASSERT_EXIT({ separatedTestProc(); }, ::testing::ExitedWithCode(0), ".*" ); + + // コントロールプロセスに終了指示を出して終了を待つ + CControlProcess_Terminate(szProfileName); // コントロールプロセスが終了すると、INIファイルが作成される ASSERT_TRUE( fexist( iniPath.c_str() ) ); From 428d7db73170e2abcad27c1e9ee785d7d6fd01ed Mon Sep 17 00:00:00 2001 From: berryzplus Date: Thu, 11 Feb 2021 19:01:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unittests/code-main.cpp | 34 +++++++++++++++++--------------- tests/unittests/test-winmain.cpp | 27 ++++++++++++++----------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/tests/unittests/code-main.cpp b/tests/unittests/code-main.cpp index f67ebaad56..015f4a4685 100644 --- a/tests/unittests/code-main.cpp +++ b/tests/unittests/code-main.cpp @@ -33,12 +33,13 @@ #include #include -#include +#include #include #include #include -#include "debug/Debug2.h" +#include "basis/primitive.h" +#include "util/string_ex.h" #include "StartEditorProcessForTest.h" /*! @@ -49,25 +50,26 @@ */ int StartEditorProcessForTest(std::wstring_view commandLine) { - // 実行中モジュールのインスタンスハンドルを取得する - HINSTANCE hInstance = ::GetModuleHandleW(nullptr); + //戻り値は0が正常。適当なエラー値を指定しておく。 + int ret = -1; - // WinMainに渡すためのコマンドライン - std::wstring strCommandLine(commandLine); + // コマンドラインに -PROF 指定がない場合は異常終了させる + if (std::regex_search(commandLine.data(), std::wregex(LR"(-PROF\b)", std::wregex::icase))) { + // 実行中モジュールのインスタンスハンドルを取得する + HINSTANCE hInstance = ::GetModuleHandleW(nullptr); - // コマンドラインに -PROF 指定がない場合は例外を投げて異常終了させる - if (!std::regex_search(strCommandLine, std::wregex(LR"(-PROF\b)", std::wregex::icase))) { - throw std::runtime_error("profileName is missing.."); - } + // WinMainに渡すためのコマンドライン + std::wstring strCommandLine(commandLine); - // ログ出力 - printf("%s(%d): launching process [%ls]\n", __FILE__, __LINE__, strCommandLine.c_str()); + // ログ出力 + std::wcout << strprintf(L"%hs(%d): launching process [%s]", __FILE__, __LINE__, commandLine.data()) << std::endl; - // wWinMainを起動する - const int ret = wWinMain(hInstance, nullptr, strCommandLine.data(), SW_SHOWDEFAULT); + // wWinMainを起動する + ret = wWinMain(hInstance, nullptr, strCommandLine.data(), SW_SHOWDEFAULT); - // ログ出力(途中でexitした場合は出力されない) - printf("%s(%d): leaving process [%ls] => %d\n", __FILE__, __LINE__, strCommandLine.c_str(), ret); + // ログ出力(途中でexitした場合は出力されない) + std::wcout << strprintf(L"%hs(%d): leaving process [%s] => %d\n", __FILE__, __LINE__, commandLine.data(), ret) << std::endl; + } return ret; } diff --git a/tests/unittests/test-winmain.cpp b/tests/unittests/test-winmain.cpp index d25af7623d..7371267754 100644 --- a/tests/unittests/test-winmain.cpp +++ b/tests/unittests/test-winmain.cpp @@ -68,7 +68,7 @@ struct handle_closer }; //! HANDLE型のスマートポインタ -typedef std::unique_ptr::type, handle_closer> handleHolder; +using handleHolder = std::unique_ptr::type, handle_closer>; /*! * WinMain起動テストのためのフィクスチャクラス @@ -135,12 +135,12 @@ class WinMainTest : public ::testing::TestWithParam { * CControlProcess::WaitForInitializedとして実装したいコードです。本体を変えたくないので一時定義しました。 * 既存CProcessFactory::WaitForInitializedControlProcess()と概ね等価です。 */ -void CControlProcess_WaitForInitialized( LPCWSTR lpszProfileName ) +void CControlProcess_WaitForInitialized(std::wstring_view profileName) { // 初期化完了イベントを作成する std::wstring strInitEvent( GSTR_EVENT_SAKURA_CP_INITIALIZED ); - if( lpszProfileName && lpszProfileName[0] ){ - strInitEvent += lpszProfileName; + if (profileName.length() > 0) { + strInitEvent += profileName; } auto hEvent = ::CreateEventW( NULL, TRUE, FALSE, strInitEvent.data() ); if (!hEvent) { @@ -163,7 +163,7 @@ void CControlProcess_WaitForInitialized( LPCWSTR lpszProfileName ) * CControlProcess::Startとして実装したいコードです。本体を変えたくないので一時定義しました。 * 既存CProcessFactory::StartControlProcess()と概ね等価です。 */ -void CControlProcess_Start( LPCWSTR lpszProfileName ) +void CControlProcess_Start(std::wstring_view profileName) { // スタートアップ情報 STARTUPINFO si = { sizeof(STARTUPINFO), 0 }; @@ -171,19 +171,22 @@ void CControlProcess_Start( LPCWSTR lpszProfileName ) si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWDEFAULT; - WCHAR szExePath[MAX_PATH]; - ::GetModuleFileNameW( NULL, szExePath, _countof(szExePath) ); + const auto exePath = GetExeFileName(); + + std::wstring strProfileName; + if (profileName.length() > 0) { + strProfileName = profileName; + } - CNativeW cmemCommandLine; - cmemCommandLine.AppendStringF( L"\"%s\" -NOWIN -PROF=\"%s\"", szExePath, lpszProfileName ); + std::wstring strCommandLine = strprintf(LR"("%s" -PROF="%s" -NOWIN)", exePath.c_str(), strProfileName.c_str()); - LPWSTR pszCommandLine = cmemCommandLine.GetStringPtr(); + LPWSTR pszCommandLine = strCommandLine.data(); DWORD dwCreationFlag = CREATE_DEFAULT_ERROR_MODE; PROCESS_INFORMATION pi; // コントロールプロセスを起動する BOOL createSuccess = ::CreateProcess( - szExePath, // 実行可能モジュールパス + exePath.c_str(), // 実行可能モジュールパス pszCommandLine, // コマンドラインバッファ NULL, // プロセスのセキュリティ記述子 NULL, // スレッドのセキュリティ記述子 @@ -203,7 +206,7 @@ void CControlProcess_Start( LPCWSTR lpszProfileName ) ::CloseHandle( pi.hProcess ); // コントロールプロセスの初期化完了を待つ - CControlProcess_WaitForInitialized( lpszProfileName ); + CControlProcess_WaitForInitialized(profileName); } /*!