コマンドライン引数

コマンドライン引数とは

プログラムは起動時にパラメーターを渡すことができます。
プログラムはそのパラメーターによって通常の起動とは違う処理をさせることができます。

例えばWindowsのメモ帳を開く場合、プログラムアイコンをダブルクリックするなどでそのまま起動すると中身のない新規ファイルが開かれます。
しかしプログラムアイコンに何らかのテキストファイルをドラッグ&ドロップすれば、そのファイルが開かれた状態でメモ帳が起動します。

メモ帳の通常起動
メモ帳にファイルをドラッグ&ドロップして起動

実行ファイル(○○.exe)にファイルをドラッグ&ドロップする操作は、以下のような起動パラメーターをプログラムに渡して起動するのと同じ意味になります。
コマンドプロンプトから起動

「C:\Program.cs」というのはドラッグ&ドロップしたファイルのパス(ディスク上の場所)です。
この文字列をコマンドライン引数といいます。
メモ帳はこの文字列を元にファイルを開きます。

ファイルのパスをコマンドライン引数に指定して起動するとそのファイルが開かれた状態でメモ帳が起動するのは、メモ帳がそのように作られているからです。
プログラムがどのようなコマンドライン引数(文字列)を受け取れるかはそのプログラム次第です。

コマンドライン引数を受け取る

C#でコマンドライン引数を受け取るには、Main関数の引数を利用します。


//argsにコマンドライン引数が格納されている
static void Main(string[] args)
{
    if(args.Length == 0)
    {
        Console.WriteLine("何かファイルをドラッグ&ドロップしてください");
    }
    else
    {
        for (int i = 0; i < args.Length; i++)
            Console.WriteLine(args[i]);
    }
    Console.ReadLine();
}

Main関数の引数にstring型の配列を指定します。
Visual Studioが自動生成するコードならば最初からargsという名前で記述されているはずです。
このstring型配列argsにコマンドライン引数が格納されています。

このコードをビルドしてそのまま起動しても「何かファイルをドラッグ&ドロップしてください」と表示されるだけです。
ビルドして作成された実行ファイルに対して適当なファイルをドラッグ&ドロップしてみてください。
そのファイルのパスが表示されるはずです。

C¥test.txt

ビルドした実行ファイルはプロジェクトフォルダ内の「bin\Debug」フォルダ内にあります。

複数のファイルを同時にドラッグ&ドロップすればその数だけパスが表示されます。
コマンドライン引数は半角スペースを区切り文字としてそれぞれの文字列をstring型配列の要素に格納します。

渡されるのはただのstring型配列ですから、後は自由に加工して起動パラメーターを作ることができます。

Visual Studioでのビルド時にコマンドライン引数を渡す

プログラムの作成中は、その動作確認のために毎回ビルド後にコマンドライン引数を渡して起動するのは面倒ですし、何よりデバッグ作業ができません。
その場合はプロジェクトの設定でビルド後に自動でコマンドライン引数を渡してデバッグモードで起動することができます。

上部メニューから「プロジェクト→(プロジェクト名)のプロパティ」を開きます。
プロジェクトのプロパティを開く

開いた設定画面の左側から「デバッグ」を選択し、右側の「コマンドライン引数」の欄にコマンドライン引数を記述します。
プロジェクトのプロパティでコマンドライン引数を設定

ここで設定した文字列がビルド後にコマンドライン引数として渡されることになります。

簡単なサンプル

コマンドライン引数を使用した簡単なサンプルコードです。

以下のプログラムはコマンドライン引数に指定したファイルをテキストファイルとして開き、コンソールに出力します。
文字エンコーディングはUTF-8、UTF-16、Shift_JISに対応していて、オプションで切り替えることができます。


using System;
using System.IO;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //引数なし
            if (args.Length == 0)
            {
                Console.WriteLine("テキストファイルをコマンドライン引数に指定してください。");
                Console.WriteLine("使い方:");
                Console.WriteLine("ファイル名 [-enc encoding]");
                Console.WriteLine("encodingはUTF-8、UTF-16、Shift_JISに対応しています。");
                Console.WriteLine("\nプログラムを終了します。");
                return;
            }

            if(!File.Exists(args[0]))
            {
                Console.WriteLine($"{args[0]}が見つかりません。");
                Console.WriteLine("プログラムを終了します。");
                return;
            }

            //文字エンコーディング
            var encoding = Encoding.UTF8;
            if (args.Length >= 3 && args[1].ToLower() == "-enc")
            {
                switch (args[2].ToLower())
                {
                    case "utf16":
                    case "utf-16":
                        encoding = Encoding.Unicode;
                        break;
                    case "shift-jis":
                    case "shift_jis":
                        Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
                        encoding = Encoding.GetEncoding("Shift_JIS");
                        break;
                    case "utf8":
                    case "utf-8":
                        break;
                    default:
                        Console.WriteLine($"'{args[2]}'は不明な文字エンコーディングです。");
                        Console.WriteLine($"ファイルをUTF-8で開きます。");
                        Console.WriteLine();
                        break;
                }
            }
        
            using(var sr = new StreamReader(args[0], encoding))
            {
                int c = 0;
                while ((c = sr.Read()) >= 0)
                    Console.Write((char)c);
            }
        
            Console.WriteLine("\n\n読み込み終了");
            Console.WriteLine("プログラムを終了します。");
        }
    }
}

コマンドライン引数に何も指定せずにプログラムが起動すると、プログラムの使い方の説明を表示してプログラムを終了します。
コマンドライン引数にファイル名を指定すると、ファイルをUTF-8で開いて中身を表示します。

ファイル名に続いて「-enc エンコーディング名」を指定すると、指定の文字エンコーディングでファイルを開いて中身を表示します。
このようなコマンドライン引数を利用してプログラムの動作を制御する方法をコマンドラインオプションと言います。
これはコンソール画面からプログラムを起動する際に使用されます。
例えばこのプログラムの名前が「FileReader.exe」だとすると、以下のようなコマンドでファイルを読み込むことができます。


C:>cd (プログラムの場所)
C:>FileReader test.txt -enc Shift_JIS

「cd」は現在のフォルダを移動するWindowsのコマンドです。
コマンドプロンプトでは、別のドライブに移動したい場合は「/d」オプションが必要です。


C:>cd /d E:\Test\

PowerShellでは/dオプションは必要ありません。
ただしexeファイルの実行は、ファイル名の前に「./」が必要です。
(カレントディレクトリにあるexeファイルを実行する場合)


PS C:>cd (プログラムの場所)
PS C:>./FileReader test.txt -enc Shift_JIS

パス名に半角スペースが含まれる場合、パス文字列をダブルクォーテーションで囲う必要があります。


C:>FileReader "C:\my file.txt" -enc Shift_JIS