Теперь я могу несколько раз создавать экземпляр одной и той же службы Windows, которую я создал.
Мне удается установить отдельные экземпляры с помощью «InstallUtil.exe /servicename=TestX".
». Это означает, что каждый экземпляр отображается в списке вмои службы Windows, как и должно (см. экземпляр службы test1 ), но остаются остановленными.
Я видел во многих потоках, что люди используют таймер для автоматического перезапуска службы.Это действительно необходимо?
Можно ли просто перезапустить его из приложения-клиента с помощью «ServiceController», который я пробовал, но безуспешно.
Используя последний подход, я получаю сообщение об ошибке, в котором говорится, что на моем локальном компьютере невозможно найти точку конца трубы.
Я не уверен, что это на самом деле связано с моей проблемой, но нужно лиустановить разные конечные точки для каждого нового экземпляра моего сервиса?
Вот что я сделал, чтобы разрешить несколько экземпляров службы:
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>
Вот что делает мой прокси-конструктор:
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») согласно здесь .
Обратите внимание, что служба найдена, но перезапуск / использование ее - это другое дело.Вот мой действительный код клиента:
...
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]),
};
...