【Windowsサービス】Windowsサービス ~ WCFでクライアント側と通信する ~

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37948659.html
で、簡単なWindowsサービスを作成できたので、
今度は、プロセス間通信(IPC:Inter Process Communication)を実現できる
WCFWindows Communication Foundation)を使って、
以下の「構成」のような「Windowsサービス - 他のアプリ」とのやり取りをする

構成

サービス側
 * Windows Service (WindowsService1)
クライアント側
 * Windows Form (SampleForm)
  + button x 1
  + textBox x 2
  + label x 1

■ サンプル

前提条件

 * WCFを使うために「System.ServiceModel」を参照追加しておくこと
 * サービス側、クライアント側両方とも「管理者として実行」で実行されていること
  => Visual Studio で実行するなら、Visual Studioを「管理者として実行」で実行する

サービス側 (WindowsService1)

https://blogs.yahoo.co.jp/dk521123/37948659.html
をベースに
https://blogs.yahoo.co.jp/dk521123/31872515.html
WCFの実装を組み込む。

 => 「installutil WindowsService1.exe」でWindowsサービスをインストールし、
    サービスとして開始させておく。
Service1.cs
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceProcess;

namespace WindowsService1
{
  public partial class Service1 : ServiceBase
  {
    private ServiceHost host;

    public Service1()
    {
      InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
      Uri baseUri = new Uri(@"http://localhost:8888/SampleWcfService");
      try
      {
        this.host = new ServiceHost(typeof(SampleWcfService), baseUri);
        var binding = new BasicHttpBinding();
        this.host.AddServiceEndpoint(typeof(ISampleWcfService), binding, "Plus");
        this.host.Open();

        EventLog.WriteEntry(String.Format("{0} : Starting Windows Service...", DateTime.Now));
      }
      catch (Exception ex)
      {
        Console.Write(ex.Message);
      }
    }

    protected override void OnStop()
    {
      EventLog.WriteEntry(String.Format("{0} : Stopping Windows Service...", DateTime.Now));
      if (this.host != null)
      {
        this.host.Close();
      }
      EventLog.WriteEntry(String.Format("{0} : Done Windows Service...", DateTime.Now));
    }
  }

  [ServiceContract]
  public interface ISampleWcfService
  {
    [OperationContract]
    int Plus(int value1, int value2);
  }

  public class SampleWcfService : ISampleWcfService
  {
    public int Plus(int value1, int value2)
    {
      Trace.WriteLine("Called me?");
      return value1 + value2;
    }
  }
}

クライアント側 (SampleForm)

using System;
using System.ServiceModel;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      var endpointAddress = new EndpointAddress("http://localhost:8888/SampleWcfService/Plus");
      using (var channel = new ChannelFactory<ISampleWcfService>(new BasicHttpBinding()))
      {
        var service = channel.CreateChannel(endpointAddress);
        int value1 = Convert.ToInt32(this.textBox1.Text);
        int value2 = Convert.ToInt32(this.textBox2.Text);
        this.label1.Text = service.Plus(value1, value2).ToString();
        channel.Close();
      }
    }
  }

  [ServiceContract]
  public interface ISampleWcfService
  {
    [OperationContract]
    int Plus(int value1, int value2);
  }
}

動作確認

 * Formを起動しTextBoxに「31」「12」を入れて、ボタン押下すると、
   「43」と表示されるはず。

■ 補足:Javaでのアクセス

 * WCFJavaクライアントでアクセスする場合は、以下の関連記事を参照。
WCF ~ WCFJavaクライアントでアクセスする ~
https://blogs.yahoo.co.jp/dk521123/37962361.html