作成環境は次のとおり
- OS:Windows Vista Enterprise
- IDE: Visual Studio 2008 Professional
- .NETバージョン:3.5
- 動作環境:ローカル接続。通信にnetTcpBindingを使用。
WCFSample002で作成したサンプルではWindowsアプリケーションがWCFサービスをホストするようにしました。今回は、Windowsサービスとして、WCFサービスをホストするプログラムを作成します。今回はnamedpipe(名前つきパイプであってる?)で接続します。また、WCFサービスの定義をApp.configで行わずに、プログラム内で定義を行います。
1.プロジェクトの作成とWCFサービスプロジェクト作成
Windows Serviceテンプレートを選択してWCFSample003というソリューションとプロジェクトを新規作成します。
2.WCFSample002で作成したプログラムをプロジェクトに追加とアセンブリ参照の設定
WCFSample002で作成した、Product.cs,ProductService.cs,IProductService.csをプロジェクトに追加します。ネームスペースをWCFSample002からWCFSample003に変更します。コピーしたファイルを開いて、ネームスペースを右クリックし[Refactor]→[Rename]でRenameダイアログでWCFSample003に変更できます。ソースプログラムはWCFSample002を参照して下さい。
プロジェクトの参照に、System.ServiceModel.dll,System.Runtime.Serialization,System.Confuguration.dllのアセンブリを参照に追加します。
3.App.configの編集
作成し、次のようにDBコネクション用にconnectionStringを編集します。ユーザ名、パスワード、接続DB名など接続文字列は環境により変わります。今回はWCFサービスの宣言はApp.configに記載しません。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="AdventureWorksConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=AdventureWorks;User ID=【ユーザ名】;Password=【パスワード】"/>
</connectionStrings>
</configuration>
4.Windowsサービスプログラムの作成
プロジェクト作成時に作成されたService1.csのファイル名をProductServiceHost.csに変更し、次のように編集します。プログラム上でnamed pipeで接続するようにエンドポイントを設定すると同時に、メタデータ交換用のエンドポイントを作成しています。クライアントからプロキシクラスを作るときはメタデータ接続用のURIを指定してプロキシを作成します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using WCFSample003.Production;
using System.ServiceModel.Description;
namespace WCFSample003
{
public partial class ProductServiceHost : ServiceBase
{
public ProductServiceHost()
{
InitializeComponent();
this.ServiceName = "WCFSample003 Product Service";
this.CanStop = true;
this.AutoLog = true;
}
private ServiceHost _serviceHost;
protected override void OnStart(string[] args)
{
_serviceHost = new ServiceHost(typeof(WCFSample003.Production.ProductService));
_serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior());
NetNamedPipeBinding binding = new NetNamedPipeBinding();
_serviceHost.AddServiceEndpoint(typeof(IProductService), binding, "net.pipe://localhost/ProductServicePipe");
_serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), "net.pipe://localhost/ProductServicePipe/MEX");
_serviceHost.Open();
}
protected override void OnStop()
{
_serviceHost.Close();
}
}
}
5.Installerプログラムの作成
ProductServiceHost.csをソリューションエクスプローラからダブルクリックして、Design Viewを表示します。Design View上で右クリックし、ポップアップメニューから[Add Installer]を選択します。
作成されたProjectInstaller.csのDesign View上でserviceProcessInstaller1を選択し、プロパティのAccountにLocalSystemを設定します。serviceInstaller1を選択して、プロパティのServiceNameをWCFSample003Serviceに,StartTypeをAutomaticに変更します。
6.ビルドとサービスのインストール
設定が完了したらソリューションをビルドします。ビルド後、Admin権限でVisual Studio 2008のコンソールを開いてビルドされたexeファイルのあるディレクトリに移動して、installutil WCFSample003.exeを実行する。

管理者としてプログラムを実行するには
Visual Studio 2008 Command PromptのアイコンをShiftを押しながら(Shiftはいらないかも)右クリックすると、コンテキストメニューにRun as administratorというメニューが追加表示されるので、選択します。
エラーが発生しなければAdministrative ToolsからServicesを選択してサービスがインストールされていることを
確認します。サービスは実行されていませんので、Startしておきます。

再インストールしたい場合
一度サービスをアンインストールします。installutil /u WCFSample003.exe
参考URL:msdn.microsoft.com/library/ja/default.asp
7.テストクライアントの作成
ソリューションを右クリックしてWindows Console Applicationを新規作成します。WCFSample003.Clientというプロジェクト名で作成しました。WCFサービスを参照してプロキシクラスを作成し、クライアントプロジェクトをスタートアッププロジェクトにします。

クライアントプログラムの内容はWCFSample002で作成したものとほぼ同じです。(下記参照)。プロキシクラスのネームスペースはサービスの参照追加時に設定した名前で変わります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WCFSample003.Client.ServiceReference1;
namespace WCFSample003.Client
{
class Program
{
static void Main(string[] args)
{
ProductServiceClient proxy = new ProductServiceClient("NetNamedPipeBinding_IProductService");
int[] productIDs = proxy.GetProductIDs();
foreach (int productID in productIDs)
{
Console.WriteLine("Product ID: " + productID);
Product product = proxy.GetProductByID(productID);
Console.WriteLine("Name: " + product.Name);
Console.WriteLine("Color: " + product.Color);
Console.WriteLine("ListPrice: " + product.ListPrice);
}
proxy.Close();
Console.WriteLine("終了するにはなにかキーを押してください。");
Console.ReadLine();
}
}
}
8.実行結果
クライアントプログラムを実行すると、次のようにコンソールが出力されます。(動かない場合はサービスがStart状態であることを確認してください。)
