* 今更ながらの GetCommmandLine 。 2023/05/25 この話も 標準 C の ライブラリー の 引数リストや 標準の WinMain を通して 与えられた コマンドラインを 受け取って作成するプログラムには若干遠い話になりそうです。 殆どの プログラムは 立ち上がった時に オプション やら 動作の為に 何らかの コマンドラインを受け取って 動作する様に出来ています。 プログラムが立ち上がる時にコマンドラインを取得する方法はコード処理 リンクの方法によってそれぞれ違い ますが 此処 ソフトの子物たちの プログラムは サイズを削るために殆どが デフォールトライブラリーは すべて無視 してリンクしています。 したがって int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { は 使用せずに void __cdecl WinMainCRTStartup( void ) { から始まっています。 こうする事で デフォールトライブラリー はリンクせずに 実行ファイルを作成出来るのでてサイズダウンが 見込めます。その代わり WinMain( は通らないので LPSTR lpCmdLine は当然ですがえられません。 WinMain(HINSTANCE hInstance, を通常通りリンクすれば LPSTR lpCmdLine, は 与えられた コマンドライの 先頭ですが 却って此では不便な事も出てきてしまいます。 プログラムを作成している時に 自分と同じ所に有る *.txt とか 設定ファイル *,ini を作りたい時が有りますが もちろん これらの Path は GetModuleFileName( NULL, (LPSTR)buf, MAX_PATH ) でも取得出来るのですが GetCommmandLine() で 自分の Pass + 与えられた CommandoLine で 得られる事を考えると この方が統一して 得られるし バッファも 実在しているので無駄も有りません。 ただ GetCommmandLine も Windows 98 からの使用から 同じように使用しているので 自分の Path の表し方が 二種類有って 途中に Space が有る時には "Path" という風に " で囲ってくる時 途中に Space が無い時には Path と言う事だったのですが この辺の正確な事ははっきり書いてある物が見つかりません。 なんとなく 新しい Windows ( NT系か ) は必ず " で囲って 来ているのではないかと思います。 ( 此も はっきりしなくて思い切って 検証は していませんし 各Windows環境も 残念ながら失われています。) したがって この GetCommmandLine から 自分の Path を切り出す。コードは lpCmdLine = GetCommandLine(); if ( *lpCmdLine == '"' ) { // '"' を探す lpCmdLine = lpCmdLine + 1; do { lpCmdLine++; } while ( *lpCmdLine && ( *lpCmdLine != '"' ) ); } else { // ' ' を探す do { lpCmdLine++; } while( *lpCmdLine && ( *lpCmdLine != ' ' ) ); } lpe = lpCmdLine; // 此が自分の Path + 1 while ( ( *lpCmdLine == ' ') || ( *lpCmdLine == '"') ) lpCmdLine++; //' ' '"' = 0x22 を除いておく // 此が 与えられた コマンドライン と 言う 二本立てで 此まで継続して来ていましたが 1つは 二本立てが気に入らない。 二つ目は 探すのが '"' or ' ' or '\0' と言うのもなんか間接的な気もします。 もっと確実なのは 自分の Path は 必ず ・・・.exe\0 or ・・・.exe or ・・・.exe" だろうという事です ( ・・・.EXE も有るかも ) と 言う事で 新たに lpCmdLine = GetCommandLine(); while( *lpCmdLine ) { if ( ( *lpCmdLine++ == '.' ) && ( ( *(PINT)lpCmdLine & 0xDDDFDFDF ) == 0x455845 ) ) { // \0 ' ' '"' = 0 break; } } if ( *lpCmdLine == 0 ) goto Exit_Proc; // Exit_Pro 絶対安全の為 lpCmdLine = lpCmdLine + 3; // while ( ( *lpCmdLine == ' ') || ( *lpCmdLine == '"') ) lpCmdLine++; // //' ' '"' = 0x22 を除いておく if ( *lpCmdLine == '"') lpCmdLine++; // '"' で囲まれていたので次 if ( *lpCmdLine == ' ') lpCmdLine++; の コードを使用してみることにしました。 探すのは .exe\0 .exe" .exe で 自分の最後ではっきりしています。 ( ( *(PINT)lpCmdLine & 0xDDDFDFDF ) の所がちょっと毎回では重い気がしますが '.' の後だけですからそれ程の 負荷には ならないだろうと思います。 この方法を 同時に 自分の Path も切り出す時など 重複の無くなる都合の良い時に使用して行こうかと思っています。 どちらにしても 間違いも無く正しく動くし それ程の変化もありませんが 趣味の範疇の話です。