作为Windows服务的一部分安装的我的WCF服务停止 - 如何在不使用Timer的情况下从我的客户端启动它?

问题描述 投票:-1回答:1

我现在能够多次实例化我创建的同一个Windows服务。 我设法使用“InstallUtil.exe / servicename = TestX”安装单个实例。 这意味着每个实例都应该在我的Windows服务中列出(请参阅Service instance test1),但仍然停止。

我在许多线程中看到人们使用Timer自动重新启动服务。这真的有必要吗? 是否可以使用“ServiceController”从aclient应用程序重新启动它,我已经尝试但没有成功。

使用后一种方法,我收到一个错误,说我的本地机器上找不到管道终点。 我不确定这实际上与我的问题有关,但是我是否需要为每个新创建的服务实例设置不同的端点?

以下是我为允许多个服务实例化所做的工作:

namespace MyService.Service
{
    [RunInstaller(true)]
    public partial class MyServiceInstaller : Installer
    {
        public MyServiceInstaller()
        {
            InitializeComponent();
        }

        // Override Install/Uninstall to allow to run various instances of the same Service
        // Install via CMD from running from C:\Windows\Microsoft.NET\Framework\v4.0.30319:
        //    InstallUtil.exe /servicename=test2 Path\bin\Debug\MyService.Service.exe: 
        public override void Install(System.Collections.IDictionary stateSaver)
        {
            RetrieveServiceName();
            base.Install(stateSaver);
        }

        // To uninstall:
        //   InstallUtil.exe -u /servicename=test2 Path\bin\Debug\MyService.Service.exe: 
        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            RetrieveServiceName();
            base.Uninstall(savedState);
        }

        // Set up name of each service instance
        private void RetrieveServiceName()
        {
            var serviceName = Context.Parameters["servicename"];
            if (!string.IsNullOrEmpty(serviceName))
            {
                this.serviceInstaller1.ServiceName = serviceName;
                this.serviceInstaller1.DisplayName = serviceName;
            }
        }
    }
}

这是来自App.config(我认为这与我的问题无关,但如果我在这里做错了,请告诉我):

<services>
      <!-- This section is optional with the new configuration model introduced in .NET framework 4.0 -->
      <service name="MyService.Service.MyService" behaviorConfiguration="MyServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/My.Service/"/>
          </baseAddresses>
        </host>

        <!-- This endpoint is exposed at the base address provided by host -->
        <endpoint address="MyServiceAddr" binding="netNamedPipeBinding" contract="MyService.ServiceContract.IMyService"/>

        <!-- The mex endpoint is exposed at http://localhost:9000/MyService.Service/service/mex -->
        <endpoint address="MyServiceAddr/mex" binding="mexNamedPipeBinding" contract="IMetadataExchange"/>

      </service>
    </services>

这是我的Proxy Constructor所做的:

private MyServiceProxy(string serviceName)
{
  var ctx = new InstanceContext(MyServiceCallbackProxy.Instance);

  var binding = new NetNamedPipeBinding();
  var channelFactory = new DuplexChannelFactory<IMyServiceService>(ctx, binding,
     new EndpointAddress(Constants.ServiceBaseAddress + serviceName));

   // Create channel to a specified endpoint
    _channel = channelFactory.CreateChannel();
 }

最后,我尝试从我的客户端(使用“ServiceController”)按照here启动我的服务。 请注意,找到了服务,但重新启动/使用它是另一回事。这是我的实际客户端代码:

...
static bool serviceExists(string ServiceName)
{
 return ServiceController.GetServices().Any(serviceController =>   serviceController.ServiceName.Equals(ServiceName));
}
static void startService(string ServiceName)
{
 ServiceController sc = new ServiceController();
 sc.ServiceName = ServiceName;

 Console.WriteLine("The {0} service status is currently set to {1}", ServiceName, sc.Status.ToString());

 if (sc.Status == ServiceControllerStatus.Stopped)
 {
  // Start the service if the current status is stopped.
  Console.WriteLine("Starting the {0} service ...", ServiceName);
  try
  {
   // Start the service, and wait until its status is "Running".
   sc.Start();
   sc.WaitForStatus(ServiceControllerStatus.Running);

   // Display the current service status.
   Console.WriteLine("The {0} service status is now set to {1}.", ServiceName, sc.Status.ToString());
   }
   catch (InvalidOperationException e)
   {
    Console.WriteLine("Could not start the {0} service.", ServiceName);
    Console.WriteLine(e.Message);
   }
  }
  else
  {
   Console.WriteLine("Service {0} already running.", ServiceName);
  }
}

static void Main(string[] args)
{
 if (serviceExists("test1"))
 {
  Console.WriteLine("Service exists");
 }
 else
 {
  Console.WriteLine("Service doesn't exists");
 }

 startService("test1");

 // Connect to Proxy in order to run multiple APIs in parallel
 MyServiceProxy ServiceInst = MyServiceProxy.Instance("test1");
 …

服务主机以这种方式启动:

public MyServiceWindowsService(sting serviceName)
{
  InitializeComponent();

  // Name the service
  ServiceName = serviceName;
}

protected override void OnStart(string[] args)
{
  StartServiceHost();
}

private void StartServiceHost()
{
 // Stop the service before starting the service
 StopServiceHost();
 ServiceHost = new ServiceHost(typeof(MyService));

 // Open the ServiceHostBase to create listeners and start listening for messages
 ServiceHost.Open();
}

主要是做:

public static void Main(string[] argsIn)
{
  ServiceBase[] servicesToRun = new ServiceBase[]
  {
    new MyServiceWindowsService(argsIn[0]),
  };
...
c# service instance
1个回答
0
投票

在您的客户端中,EndPoint的地址是从Windows服务的名称动态构造的:

new EndpointAddress(Constants.ServiceBaseAddress + serviceName)

您还需要让ServiceHostStartServiceHost()中使用此地址:

Uri uri = new Uri(Constants.ServiceBaseAddress + ServiceName);
ServiceHost = new ServiceHost(typeof(MyService), uri);

ServiceHost.Open();
© www.soinside.com 2019 - 2024. All rights reserved.