• ベストアンサー

コンソールアプリの起動パラメータ について

・環境   XP, Borland C++ Compiler 5.5 ・使用言語   C++ コンソールアプリを作成しています。 コンパイルして出来上がったEXEのアイコンに、何かファイルを ドラッグ&ドロップすると、そのファイルがパラメータとなって EXEが起動されると思うのですが、ここで疑問があります。 (1)最大パラメータ数というのはどこかに規定されているのでしょうか。 (2)複数のファイルをドラッグ&ドロップした時に、EXEに渡される順番というのはどのように決定されるのでしょうか。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★アドバイス >数を少なくすると、問題ないのでどこに原因があるのだろうと探っていた所でした。  ↑ ・私も圧縮/解凍ソフトで同様なエラーがでて驚いたことがあります。  それで渡せる文字数に限りがあるのだと思いました。  理由は既に書いていますがパスが深い場合は少なく、パスが浅い(C:\)の場合は  たくさんのファイルを渡せましたので。今回、回答 No.4 で確認用のサンプルを  作って文字数の限界値を計算してみました。→この質問をきっかけに。 >ドラッグ&ドロップの順番の >結果的にはクリップボードに上から順番に並んでいたほうが直感的に >正しいインターフェース(?)かな?と思ったからです。  ↑  気持ちは分かります。同じ考えです。 ・でも私の環境では範囲選択してドラッグしている位置から順番に取得できました。  例えば 1~20 のファイルを範囲選択して  1 のファイルで右メニューすれば 1~20 の順番で  10 のファイルで右メニューすれば 10~20、1~9 の順番で  20 のファイルで右メニューすれば 20、1~19 の順番で  取得できました。  ※Windows XP Home SP2 の環境で順番に取得可能でした。参考に。 ・あとエラーダイアログは OS の仕様でしょうね。  渡せるフルパス領域は調べた結果では 2100 バイト前後ですのでパスが深い場合は  例えば  フルパスで 100 文字の場合では 2100÷100=21個渡せ、  フルパスで 16 文字の場合では 2100÷15=131個渡せる  事になる。 ・多分は OS の制約でしょう。  正確な文字数が分かりませんがどのソフトでも同じようなエラーダイアログが出ます。  ファイル数を減らせば出来ます。また、圧縮/解凍ソフトでは先にウインドウを  起動させてそこへドラッグ&ドロップするとファイル数に制限はなくなる。  どうも仕組みが違うようだ。→ウインドウにドラッグ&ドロップした場合は HDROP の  ハンドルで受け取れるから文字数(メモリ)の制約がないのかも。 ・またファイルを範囲選択して右メニューで『コピー』を選択するとファイル名の情報が  クリップボードにコピーされます。その後プログラムからクリップボードを取得すれば  HDROP の情報をもらえます。これなら制約もなくなるがコピーした後にプログラムを  起動させる手間がかかってします。 最後に: ・エクスプローラの右メニュー(『送る』ではない)の場所に項目を追加してシェル拡張  として受け取ると範囲選択したすべてのファイルを受け取れるようです。  そういうソフトを普段使ってファイル名、フルパス名をクリップボードにコピーしてます。 ・ちょっと調べたらこのソフトでは 2698 個のファイルを受け取れてフルパス名の文字数は  243,854 バイトになりました。よってシェル拡張として作成すれば良いようですが  あまり詳しくありません。参考に。 ・以上。

otaks
質問者

お礼

ご回答ありがとうございます。 > 例えば 1~20 のファイルを範囲選択して > 1 のファイルで右メニューすれば 1~20 の順番で > 10 のファイルで右メニューすれば 10~20、1~9 の順番で > 20 のファイルで右メニューすれば 20、1~19 の順番で > 取得できました。 前のご回答では私が意図を読み違えていたようです。(クリックした位置は関係なしに、 選択した一番上のファイルからと思っていました。) 私の環境でも上記の挙動になりました。 >どうも仕組みが違うようだ。→ウインドウにドラッグ&ドロップした >場合は HDROP のハンドルで受け取れるから文字数(メモリ)の制約がないのかも。 今後機会があったら試してみようと思います。 >・エクスプローラの右メニュー(『送る』ではない)の場所に項目を追加してシェル拡張 > として受け取ると範囲選択したすべてのファイルを受け取れるようです。 ファイル名取得のソフトウェアとして実用に耐えるものを作ろうとしたらこの方法を使えばよいのですね。 (というかもう作られてるみたいだけど。でもこのソフトウェアは勉強もかねているので問題ないです。) 色々と有用な情報をたくさんありがとうございました。感謝します。

その他の回答 (5)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★ちょっとお聞きしたいです。 >どこかに仕様として明言されていないものなんですね・・ >・パラメータの長さ最大 >・EXEに渡される順番 >Windowアプリなら数は制限されないだろうことも・・  ↑  なぜ、パラメータの最大長や引数の最大個数を知りたいのでしょうか?  引数のメモリ確保を固定値として使いたいのでしょうか?  あとドラッグ&ドロップの順番も順番を気にしないといけないのでしょうか? ・単なる好奇心なら良いのですが、何かプログラムではっきりと明言されていないと  困ることでもありますか?  いろいろとお聞きしたいです。理由を。何かお困りかな? ※今のところ『どこかに仕様として明言』されている記述は見たことがないです。私はね。 その他: ・パラメータの最大長は回答 No.4 のようにカウントすれば得られるのでその値を  使ってメモリ確保とか、引数の個数を任意個として処理すれば問題ないと思う。  また、ドラッグ&ドロップも順番が崩れるのならソートしてから何かの処理を  行うようにすれば良いと思いますが…。ちなみに私の環境ではドラッグ&ドロップ  した位置から順番にファイル名が得られますけど。 ・以上。

otaks
質問者

補足

補足します。 >なぜ、パラメータの最大長や引数の最大個数を知りたいのでしょうか? 現在簡単なソフトウェアを作っておりまして、エクスプローラでファイルを選択状態にして、右クリック-送る。で呼び出して、(この呼び出し方をすると選択したファイルのフルパスがパラメータとして渡される)ファイル名をクリップボードに出力するというものです。 実際にこのソフトウェアを使ってみると、たくさんファイルを選択して呼び出したときには、エラーダイアログ --------------------------- C:\Documents and Settings\USER_1\SendTo\ver2.exe --------------------------- 指定されたデバイス、パス、またはファイルにアクセスできません。アクセス許可がない可能性があります。 --------------------------- OK --------------------------- が出てしまいました。 数を少なくすると、問題ないのでどこに原因があるのだろうと探っていた所でした。 >引数のメモリ確保を固定値として使いたいのでしょうか? 内部ではString型を使って処理しており(?)特に固定値として使いたいとかではないと思います。 >あとドラッグ&ドロップの順番も順番を気にしないといけないのでしょうか? このソフトウェアを使用する際、(このソフトウェアは複数ファイルに対応しており、クリップボードに改行区切りで出力します)使用する人は選択したファイルが、結果的にはクリップボードに上から順番に並んでいたほうが直感的に正しいインターフェース(?)かな?と思ったからです。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★回答者No.2です。 ・コマンドラインでは 255 文字が限界ですが、ドロップした場合は回答者 No.3 さんが  実験した結果が正しいです。コマンドラインとはまた違う文字数のようですね。 >2046文字まではOKでした  ↑  これぐらいでしょうね。文字数。  回答 No.2 でドロップ出来た数が 20~25 個となっていますので1つのファイルのパスが  100文字だと考えると 20×100=2000 文字となりおよそあっています。 ・回答者 No.3 と同じようなサンプルを作って目で確認してみてはどうでしょうか?  私もサンプルを作って確認してみました。 サンプル: #include <stdio.h> #include <string.h> #include <windows.h> // メイン関数 int main( int argc, char *argv[] ) {  LPTSTR lpCmdline = GetCommandLine();  int i, len = 0;    for ( i = 0 ; i < argc ; i++ ){   printf( "%d: %s\n", i, argv[i] );   len += (int)strlen( argv[i] );   len++; // 引数間の空白も加算  }  printf( "文字数=%d(%d)\n", len, lstrlen(lpCmdline) );  getchar();  return 0; } 結果発表: (1)マイ ピクチャでドロップ  最大 23 個までファイルを渡せた。  このときの文字数は argv[n] を加算したものが 2189 文字で  Win32 API から引数文字列を取得して文字数を数えると 2236 文字でした。 (2)C:\ でドロップ  最大 158 個までファイルを渡せた。  このときの文字数は argv[n] を加算したものが 2103 文字で  Win32 API から引数文字列を取得して文字数を数えると 2110 文字でした。 ・実験結果ではおよそ 2100 文字まで受け取れるようです。  また C:\ のパスが短い場所からドロップすると 158 個も渡せました。  ファイル名が1文字の場合はもっと多いファイル数を渡せるはずですが  実用ではないですね。 ※Windows XP Home SP2 結論: ・個数よりも文字数に制限されているようだ。  以上。

otaks
質問者

お礼

ご回答ありがとうございます。 コマンドラインの255文字と言うのはコマンドラインの 仕様のことっぽいですね もう一方のがOSの仕様なのかな

otaks
質問者

補足

どこかに仕様として明言されていないものなんですね・・ ・パラメータの長さ最大 ・EXEに渡される順番 Windowアプリなら数は制限されないだろうことも・・

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

ちょっと実験してみましたが文字数制限のようです(WinXP) #include <stdio.h> #include <string.h> int main(int argc, char**argv) { int i; int len = 0; for (i = 0; i < argc; i++) { printf("%s\n", argv[i]); len += strlen(argv[i]); } printf("argc = %d len = %d\n", argc, len); getchar(); return 0; } 2046文字まではOKでした

otaks
質問者

お礼

ご回答ありがとうございます。 これは(1)に対する答えですね >2046文字まではOKでした シングルバイト文字でのことですか? No.2さんの回答とどちらが正しいんだろう…

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス >(1)最大パラメータ数というのはどこかに規定されているのでしょうか。  ↑  これはコマンドラインで渡せる文字数から決まると思います。  最大の文字数は 255 バイトなので 1 文字のファイルを引数とすると 255 から  プログラム名の長さを引き2で割った数が最大引数の数となります。  例:  a.exe なら (255-6)÷2=124 個が最大。 ・既定されているのは文字数であって最大パラメータ数としては既定はないと思います。  なので最大 255÷2=127個だと思えばよいかな。 >(2)複数のファイルをドラッグ&ドロップした時に、 >EXEに渡される順番というのはどのように決定されるのでしょうか。  ↑  ドラッグ&ドロップしたファイル位置から順番に渡されると思います。  範囲選択して一番上をドラッグするとそこから下に順番に渡されます。  でも範囲選択した中間でドラッグするとそこから下にいき、一番上からドラッグした  中間までが渡されます。イメージ沸く。  ※上記のは GUI でウインドウにドラッグ&ドロップした場合です。 ・コンソールアプリのアイコン(ショートカットのアイコンも含む)では最大20~25まで  しか渡せなかった気がします。数の既定よりもフルパスの合計の問題かと思います。  なので『C:\』のルートのファイルをドラッグ&ドロップすると多く渡せたりパスの深い  デスクトップや『マイ ドキュメント』にあるファイルを渡すと数が減る(20-25個前後)  と思います。 ・GUI アプリケーションを作ってウインドウにドラッグ&ドロップするようにすれば  数には制限されないと思いますが…。コンソールアプリで頑張る? ・以上。参考に。

otaks
質問者

お礼

ご回答ありがとうございます。 > ドラッグ&ドロップしたファイル位置から順番に渡されると思います。 これは色々なパターンで実験しましたが、そのようには ならなかったです。 また、一定のパターンも見つけることができなかったです。 そのほかはなんとなく分かりました

関連するQ&A