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



我现在能够多次实例化我创建的同一个Windows服务。
我确实设法使用"InstallUtil.exe/servicename=TestX"安装单个实例。
这意味着每个实例在我的 Windows 服务中都按原样列出(请参阅服务实例 test1),但仍然处于停止状态。

我在许多线程中看到人们使用计时器自动重新启动服务。这真的有必要吗?
是否可以使用"服务控制器"简单地从客户端应用程序重新启动它,我已经尝试过但没有成功。

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

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

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:WindowsMicrosoft.NETFrameworkv4.0.30319:
//    InstallUtil.exe /servicename=test2 PathbinDebugMyService.Service.exe: 
public override void Install(System.Collections.IDictionary stateSaver)
{
RetrieveServiceName();
base.Install(stateSaver);
}
// To uninstall:
//   InstallUtil.exe -u /servicename=test2 PathbinDebugMyService.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>

这是我的代理构造函数的作用:

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();
}

最后,我尝试从我的客户端(使用"服务控制器")启动我的服务,如下所示。
请注意,该服务被找到,但重新启动/使用它是另一回事。 这是我的实际客户端代码:

...
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]),
};
...

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

new EndpointAddress(Constants.ServiceBaseAddress + serviceName)

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

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

相关内容

最新更新