Visual StudioでWindowsアプリを作成時、バッチファイルを使用する必要が出た為、初版の事情によりsystem()でなく、CreateProcess()を使おうとした。 しかし、いざ実行すると「System.AccessViolationException」というExceptionが発生して手詰まりに…
環境
- Windows7 Pro 64bit
- Visual Studio 2010 Pro
- Windowsフォームアプリケーション
原因
「第2引数:コマンドラインの文字列」に、リテラル値を設定していた為。
解説
「第2引数:コマンドラインの文字列」に、#defineで定義した、文字列定数をセットしていた。
// before: #define DEFINE_CMD L"cmd~" CreateProcess(NULL ,DEFINE_CMD ,NULL ,NULL ,FALSE ,0 ,NULL ,NULL ,&si ,&pi); // ⇒Exception!
しかしここで設定するものというのは、システム側から書込が行われるらしい。 その為、リテラルで指定していると、書込不可領域(保護された領域)にシステムが書き込もうとする為「アクセス違反」と言われる。
修正
//after: TCHAR cmd[1024]; memcpy(cmd, DEFINE_CMD, sizeof(DEFINE_CMD)); CreateProcess(NULL ,DEFINE_CMD ,NULL ,NULL ,FALSE ,0 ,NULL ,NULL ,&si ,&pi);
割と適当な造りな気もするが。
あとがき
msdnとか読み損じがあったかも知れないが…わかった瞬間「しらねぇよ…」って思ってしまいましたとさ…