SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Android コマンド実行

【 Xamarin 記事一覧 】

1 コマンド実行

001

最初に実行画面と使用方法です。

AppenLog()は、ログ出力用のメソッドで、Cmdクラスが、コマンド実行のためのクラスです。

Cmdクラスでは、Start()でコマンドがスレッド実行されます。また、OnLogイベントで1行ごとの標準出力を取得できます。


void Button_Click(object sender, EventArgs e){
    const string cmdStr = "ping -c 5 127.0.0.1";
    AppendLog(">" + cmdStr + "\n");

    var cmd = new Cmd();
    cmd.OnLog += AppendLog;
    cmd.Start(cmdStr);
}

2 ログ出力

AppendLog()は、textViewに文字列を追加するメソッドです。スレッドから呼び出される事も想定してRunOnUiThread()で処理しています。

//ログ表示
private void AppendLog(string str){
    var textView = FindViewById<TextView>(Resource.Id.textView1);
    RunOnUiThread(() => textView.Text = textView.Text + str);
}

3 Cmdクラス

コマンド実行のためのクラスです。
コマンド実行の本体は、private Exec()であり、public Start()からスレッド実行されています。
コマンド処理が終了するまで、標準出力を逐次読取り、改行が見つかった時点で1行分の出力としてイベント処理しています。


class Cmd{
    //1行分の出力イベント
    public event OnLogDelegate OnLog;
    public delegate void OnLogDelegate(string line);

    //コマンド実行(スレッド実行)
    public void Start(string cmdStr){
        new Thread(() => Exec(cmdStr)).Start();
    }

    void Exec(string cmdStr){
        //与えられたコマンドを空白で区切ってProcessBuilderのパラメータにする
        var pb = new ProcessBuilder(cmdStr.Split(new []{' '},StringSplitOptions.RemoveEmptyEntries));
        var p = pb.Start(); //プロセス開始

        // 標準出力のストーリム
        var isr = new InputStreamReader(p.InputStream);
        var buf = new List<char>(); //1行分のバッファ
        int ch;
        while ((ch = isr.Read()) > -1) {
            buf.Add((char)ch);
            if (ch == '\n') { //1行分の出力処理
                Log(buf);
            }
        }
        Log(buf);//残余分の出力処理

        p.WaitFor(); 
        p.Destroy();
    }

    //1行分の出力処理
    void Log(List<char> buf){
        if (OnLog != null){
            //System.Text.String への変換
            var line = new System.String(buf.ToArray());
            OnLog(line); //イベント処理
        }
        buf.Clear();//バッファの初期化
    }
}

【 Xamarin 記事一覧 】