Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2019年06月17日] [更新 2019年06月18日] Delphi 一般・その他
   
コマンドライン引数の取得
動作確認等 Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32
[整理番号 - 0150]







01_コマンドラインパラメータの取得


コマンドラインは CmdLine 関数で,文字列として取得できます.
CmdLine 関数でコマンドラインの文字列を取得してしまえば,後は文字列の解析 (パース) ということになります.ParamStr 関数を使用すれば,半角の空白文字をパラメータの区切りとして各々のパラメータの値を文字列として取得できます.以下のコードはその例です.

コマンドラインパラメータには,コマンドライン引数,コマンドの引数,あるいはアプリの起動オプション,起動パラメータ等,様々な呼び方があります.



リスト1
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1Click(nil);
end;

//=============================================================================
//  コマンドラインの引数の値を取得して表示
//  パラメータは全て文字列
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LIndex : Integer;
begin
  Memo1.Lines.Clear;

  // コマンドラインの文字列を取得
  // 最初の値は EXE のフルパス
  Memo1.Lines.Add(CmdLine);
  Memo1.Lines.Add('');

  Memo1.Lines.Add('パラメータ数 : ' + IntToStr(ParamCount));

  // パラメータの値を順番に表示
  // ParamStr(0) は EXE の起動パスなので除外
  for LIndex := 1 to ParamCount do begin
    Memo1.Lines.Add(ParamStr(LIndex));
  end;
end;

end.


上のコードのプロジェクトをコンパイルして EXE を作成します.
その EXE を D:\000\TES というフォルダに作成したとします.[ファイル名を指定して実行] のダイアログ,または,コマンドプロンプトを起動して,次のコマンドを実行します.下図はコマンドプロンプトから実行した結果です.作成した EXE が実行されて,コマンドパラメータの各々の値が TMemo に表示されています.

"D:\000\TEST\Project1.exe" 日本 123.25 "ABC XYZ"


図1

エクスプローラのアドレスバーから実行する場合は,Project1.exe があるフォルダを表示して,以下のコマンドを実行します.

Project1.exe 日本 123.25 "ABC XYZ"


図2




02_コマンドラインの起動スイッチと属性値の取得


次のように,コマンドラインの引数に,属性値として値を設定したいことがあります.このような引数を「コマンドラインスイッチ」あるいは「起動スイッチ」と呼ぶことがあります.Windows ではこの起動スイッチの記号として / (スラッシュ) または - (ハイフンマイナス) を使用します.コマンドラインスイッチに関連する値,属性値は一般的に : (コロン) で区切って指定します.どちらも空白文字は挿入しないようにします.


/color:8FFF00 /size:20
-color:8FFF00 -size:20

FindCmdLineSwitch 関数を使用すると,起動スイッチの存在確認と属性値の取得ができます.以下のコードはそのサンプルです.
このサンプルでは,color という名前の起動スイッチの値と size という起動スイッチの値をコマンドラインから取得して,TPanel の色とフォントサイズを設定します.起動スイッチ color の値を色,起動スイッチ size の値をフォントサイズの値として使用します.



[備考]
FindCmdLineSwitch 関数は,スイッチではない引数,つまり,先頭に/ (スラッシュ) も - (ハイフンマイナス) もない引数の検出はできません.


リスト2
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1Click(nil);
end;

//=============================================================================
//  コマンドラインの引数の値を取得して表示
//  パラメータは全て文字列
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LValue : string;
begin
  Memo1.Lines.Clear;

  // コマンドラインの文字列を取得
  // 最初の値は EXE のフルパス
  Memo1.Lines.Add(CmdLine);

  // color スイッチの属性(関連付けの値)を取得
  if (FindCmdLineSwitch('color', LValue)) then begin
    if LValue = '' then begin
      Memo1.Lines.Add('color : no attribute');
    end else begin
      Memo1.Lines.Add('color : ' +  LValue);
      Panel1.Color := StrToInt('$' + LValue);
      Panel1.ParentBackground := False;
    end;
  end else begin
    Memo1.Lines.Add('color : not found');
  end;

  // size スイッチの属性(関連付けの値)を取得
  if (FindCmdLineSwitch('size', LValue)) then begin
    if LValue = '' then begin
      Memo1.Lines.Add('size : no attribute');
    end else begin
      Memo1.Lines.Add('size : ' + LValue);
      Panel1.Font.Size := StrToInt(LValue);
    end;
  end else begin
    Memo1.Lines.Add('size : not found');
  end;
end;

end.


上のコードをコンパイルして,D:\000\TES2 というフォルダに EXE を作成したとします.そして以下のコマンドを実行します.
上から 2 行は [ファイル名を指定して実行] のダイアログ,または,コマンドプロンプトを起動して実行する場合のコマンドラインです.その下の 2 行はエクスプローラのアドレスバーに入力して実行する場合のコマンドです.エクスプローラで実行する場合は EXE があるフォルダを表示してから実行します.


"D:\000\TEST2\Project1.exe" /color:8FFF00 /size:20
"D:\000\TEST2\Project1.exe" -color:8FFF00 -size:20
Project1.exe /color:8FFF00 /size:20
Project1.exe -color:8FFF00 -size:20


図3
実行結果
  • コマンドラインの起動パラメータの値で TPanel の色とフォントサイズを変更

起動スイッチの属性値を = で設定するようにした時は,取得した値から先頭の = を削除することで対応できます.


/color=8FFF00 /size=20

あるいは以下のように,FindCmdLineSwitch 関数のスイッチの値として color= のように = を含めて検索すれば,= よりも後の文字列が属性値として取得できます.


リスト3
  if (FindCmdLineSwitch('color=', LValue)) then begin

  if (FindCmdLineSwitch('size=', LValue)) then begin


属性値がない起動スイッチは,FindCmdLineSwitch 関数の第 2 引数を指定しないで実行すればその起動スイッチの有無を確認できます.半角の空白文字も含めた属性値は,属性値としての文字列をダブルクォーテーションで括っておきます.
ダブルクォーテーションも属性値の一部として取得するには,以下のように,ダブルクォーテーションをシングルクォーテーションで括っておきます.文字列の途中のダブルクォーテーションを文字として取得するには,ダブルクォーテーション を 2 つ続けて書いて,それをシングルクォーテーションで括っておきます.

文字列の前後にダブルクォーテーションが必要な場合,文字列を取得してからでも追加できます.


/k /name:"taro yamada" /item:"'"'"hoge '""' hoge"'"'"


図4
上のコマンドライン引数の取得結果

リスト4
procedure TForm1.Button1Click(Sender: TObject);
var
  LValue : string;
begin
  Memo1.Lines.Clear;

  // 属性値がないコマンドラインスイッチの場合
  // FindCmdLineSwitch の第 2 引数を省略して検出可能
  if FindCmdLineSwitch('k') then begin
    Memo1.Lines.Add('k : True');
  end else begin
    Memo1.Lines.Add('k : False');
  end;

  // 空白文字がある属性値の場合
  // ダブルクォーテーションで括れば検出可能
  if FindCmdLineSwitch('name', LValue) then begin
    Memo1.Lines.Add('name : ' + LValue);
  end;

  // ダブルクォーテーションも属性値として取得する場合
  // ダブルクォーテーションをシングルクォーテーションで括ってあれば検出可能
  // 文字列の途中の場合はダブルクォーテーションを 2 続けて書いて
  // シングルクォーテーションで括ってあれば検出可能
  if FindCmdLineSwitch('item', LValue) then begin
    Memo1.Lines.Add('item : ' + LValue);
  end;
end;