LoginSignup
1
2

More than 5 years have passed since last update.

別プロセスにコマンドライン引数を貯める

Last updated at Posted at 2018-09-24

別プロセスにコマンドライン引数を貯める

前提

目的

以下の場合を想定して作成した。

  • コマンドライン引数を用いて、アプリケーションを操作したい
  • アプリケーションは多重起動させたくない
  • アプリケーションはコマンドラインアプリケーションとして提供。
  • でも複数起動されたときの引数は保持したい (今回はココ)

方法

WindowsFormsApplicationBaseやSocketを使って実装する手段もあったが、
今回は簡単にアプリケーション間通信が実装できるWCFを使った。

そのため、引数を投げるクライアントと受け取り、処理するサーバに分けて実装した。

手順

参考にも記載しているが、ほぼ Part 2. Hello World WCF サーバの開発Part 3. Hello World WCF クライアントの開発 の丸写しなので読める人はそっちを見たほうがよいと思う。

1. サーバー側

Part 2. Hello World WCF サーバの開発を参考に実装

  1. 下記のコードをビルドする。
Program.cs
using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Sample.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(WcfService)))
            {
                host.AddServiceEndpoint(typeof(WcfService), new NetTcpBinding(),
                    "net.tcp://localhost:28661/Sample.Server/WcfService");

                // メタデータ取得用のエンドポイント。
                // 手順2のサービス参照の追加で必要。
                // 処理を実行するために管理者権限が必要となる。
                // サーバー処理としては無くても動く。
                host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
                host.Description.Behaviors.Remove(typeof(ServiceMetadataBehavior));
                host.Description.Behaviors.Add(new ServiceMetadataBehavior {
                    HttpGetEnabled = true,
                    HttpGetUrl = new Uri("http://localhost:8000/Sample.Server/WcfService/mex")
                });

                host.Open();
                Console.WriteLine("WCF サーバを起動しました。");

                // 終了待機用の入力待ち
                Console.ReadLine();
                host.Close();
            }
        }
    }
}
WcfService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Sample.Server
{
    // クライアント側から呼び出せる部分
    [ServiceContract]
    public class WcfService
    {
        static List<String[]> args_list = new List<String[]>();

        [OperationContract]
        public string GetMessage(string[] args)
        {
            args_list.Add(args);

            var result = string.Empty;
            foreach(string[]  args_for_res in args_list)
            {
                result = result + "\n" + String.Join(" ", args_for_res);
            }

            return result;
        }
    }
}

2. クライアント側

Part 3. Hello World WCF クライアントの開発を参考に実装

  1. クライアント側のプロジェクトを作成する。
  2. サーバー側を管理者権限で起動して待機させる。 (メタデータの公開周りで権限が必要?)
  3. プロジェクトの[参照]を右クリックし [サービス参照の追加] を開く。
  4. http://localhost:8000/Sample.Server/WcfService/mex を [アドレス] に入れて [OK] する。
  5. Connected Services > ServiceReference1 が追加される。
  6. 下記のコードからビルド。
  7. クライアント側に引数を渡して実行すると、クライアント側でサーバに保存された引数が表示される。
Program.cs
using System;

namespace Sample.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.WcfServiceClient proxy = new ServiceReference1.WcfServiceClient();
            string ret = proxy.GetMessage(args);
            proxy.Close();

            Console.WriteLine(ret);
        }
    }
}

参考

Part 1. WCF に導入されている新たな設計概念 – とあるコンサルタントのつぶやき
Part 2. Hello World WCF サーバの開発 – とあるコンサルタントのつぶやき
Part 3. Hello World WCF クライアントの開発 – とあるコンサルタントのつぶやき

備考

C#|二重起動を禁止してコマンドライン引数を取得する | 貧脚レーサーのサボり日記

WindowsFormsApplicationBase を用いて実現する方法。

今回はコマンドラインアプリケーションだったため使わなかったが、
UI付きであればこちらのが楽だろう。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2