Q&A
###前提・実現したいこと
WCFサービスを、Windowsサービスにホストさせて、クライアントとTCP通信したいと思い、下記の記事を参考に実装進めております。
How to: Host WCF in a Windows Service Using TCP
###発生している問題・エラーメッセージ
サービスホストインスタンスをオープンするときに、例外が発生します。
例外のメッセージから、サービス名やエンドポイントについて言及があるため、ホスト側のApp.Configに問題があるのかと疑いっています。しかし、サービス名やエンドポイントは適切に記述しているつもりでいますため、原因がわからず困っております。
protected override void OnStart(string[] args) { if (myServiceHost != null) { myServiceHost.Close(); } myServiceHost = new ServiceHost(typeof(Service1)); myServiceHost.Open(); // <-- InvalidOparationException発生 }
下記の例外が発生します。
エラーメッセージ "System.InvalidOperationException" "サービス 'WcfServiceLibrary1.Service1' には、アプリケーション (インフラストラクチャ以外) エンドポイントが 1 つもありません。これは、アプリケーション用の構成ファイルが見つからなかったこと、サービス名と一致するサービス要素が構成ファイル内から見つからなかったこと、またはサービス要素内でエンドポイントが定義されていないことが原因である可能性があります。" 場所 System.ServiceModel.Description.DispatcherBuilder.EnsureThereAreApplicationEndpoints(ServiceDescription description) 場所 System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) 場所 System.ServiceModel.ServiceHostBase.InitializeRuntime() 場所 System.ServiceModel.ServiceHostBase.OnBeginOpen() 場所 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) 場所 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 場所 System.ServiceModel.Channels.CommunicationObject.Open() 場所 WindowsService1.Service.OnStart(String[] args)
###Windowsサービスクラス
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceModel; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; using WcfServiceLibrary1; namespace WindowsService1 { public partial class Service : ServiceBase { internal static ServiceHost myServiceHost = null; public Service() { InitializeComponent(); } protected override void OnStart(string[] args) { try { if (myServiceHost != null) { myServiceHost.Close(); } myServiceHost = new ServiceHost(typeof(Service1)); myServiceHost.Open(); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); throw; } } protected override void OnStop() { try { if (myServiceHost != null) { myServiceHost.Close(); myServiceHost = null; } } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } } } }
###WCFサービスクラス&インターフェイス
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using WcfServiceLibrary1.Common; namespace WcfServiceLibrary1 { // メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にクラス名 "Service1" を変更できます。 public class Service1 : IService1 { public string GetData(string value) { return string.Format("You entered: {0}", value); } public Service1() { lockObj = new object(); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } } } using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using WcfServiceLibrary1.Common; namespace WcfServiceLibrary1 { // メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にインターフェイス名 "IService1" を変更できます。 [ServiceContract] public interface IService1 { [OperationContract] string GetData(string value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: ここにサービス操作を追加します。 } // サービス操作に複合型を追加するには、以下のサンプルに示すようにデータ コントラクトを使用します。 // プロジェクトに XSD ファイルを追加できます。プロジェクトのビルド後、そこで定義されたデータ型を、名前空間 "WcfServiceLibrary1.ContractType" で直接使用できます。 [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } }
###ホスト側のApp.Config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> </appSettings> <system.web> <compilation debug="true" /> </system.web> <!-- サービス ライブラリ プロジェクトの展開時に、構成ファイルの内容をホストの app.config ファイルに追加する 必要があります。System.Configuration は、ライブラリの構成ファイルをサポートしていません。 --> <system.serviceModel> <services> <service name="WcfServiceLibrary1.Service1"> <endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract="WcfServiceLibrary1.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8733/Service1" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior> <!-- メタデータ情報の開示を避けるには、 展開する前に下の値を false に設定します --> <serviceMetadata httpGetEnabled="False" httpsGetEnabled="False"/> <!-- デバッグ目的で障害発生時の例外の詳細を受け取るには、 下の値を true に設定します。例外情報の開示を避けるには、 展開する前に false に設定します --> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
###実試したこと
上記参考サイトのコードにおけるService1というクラス名が、WCFサービスとWindowsサービスで重複していたので、WindowsサービスのほうをServiceに名前変更しております。
###補足情報(言語/FW/ツール等のバージョンなど)
C#
Visual Studio 2015
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。