MonoMac/外部コマンドを実行する

提供: MonoBook
ナビゲーションに移動 検索に移動

MonoMacで外部コマンドを実行したいことも多いと思う。

実装1[編集 | ソースを編集]

dmgファイルを作ってみる[編集 | ソースを編集]

Mac OS Xのhdiutilコマンドで暗号化されたdmgファイルを作ってみる。CocoaAPIに直接的にdmgファイルを生成するものはないかとググったが、stackoverflow.comによると無いようだ。

標準入力へ文字列を渡す[編集 | ソースを編集]

hdiutilコマンドで暗号化されたdmgファイルを生成する際にはコマンドプロンプト上でパスワードの入力が求められるが、標準入力パイプ(NSPipe)を渡すことで攻略できる模様。sudoコマンドなどでも確認済み。NSPipeに渡す文字列の末尾は「\0\n」となる点に注意(「¥」は実際にはバックスラッシュMacバックスラッシュを打つには「Optionキー」を押しながら「¥キー」を押す)。

NSTaskに渡す各種パス[編集 | ソースを編集]

NSTaskに渡す外部コマンドや引数などの各種パスは相対パスではなく絶対パスでなければならないようだ。なお、NSTaskで実行する外部コマンドを「/bin/sh -c <実際のコマンド>」としてシェルを経由することで相対パスも利用できるようだが、オススメできるかは知らん。

ソース[編集 | ソースを編集]

    using System;
    using System.Drawing;
    using MonoMac.Foundation;
    using MonoMac.AppKit;
    using MonoMac.ObjCRuntime;

    class MainClass
    {
        /// <summary>
        /// osxのhdiutilコマンドでdmgファイルを作るサンプル。
        /// かつ、標準入力にパスワードを入力させるサンプル。
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        static void Main(string[] args)
        {
            // Cocoaのクラス群を使えるようにする
            NSApplication.Init();

            // 今回はウインドウ不要なのでメッセージポンプは走らせない。
            //NSApplication.Main(args);

            // 重要
            // NSPipeに渡す文字列の末尾は「\0\n」となる点に注意。
            var pass = new NSString("password\0\n");
            var data = pass.DataUsingEncoding(NSStringEncoding.UTF8);

            // パイプ
            var pipe = new NSPipe();
            pipe.WriteHandle.WriteData(data);
            pipe.WriteHandle.CloseFile();

            // タスク
            // NSTaskに指定するパス関連は絶対パスが望ましい。
            var task = new NSTask();
            task.LaunchPath = "/usr/bin/hdiutil";
            task.Arguments = new []{
                "create", 
                "-srcfolder","/Volumes/CDROM",
                "/tmp/CDROM.dmg",

                "-encryption","AES-256",// 暗号化する設定
                "-stdinpass",           // パスワードは標準入力から受け取る
            };

            // タスクにパイプを設定する
            task.StandardInput = pipe;

            // 実行する
            Console.WriteLine("launching");
            task.Launch();
            Console.WriteLine("launched");

            // 終了を待つ
            task.WaitUntilExit();
            Console.WriteLine("finish");
        }
    }

関連項目[編集 | ソースを編集]

参考文献[編集 | ソースを編集]