mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
250 lines
5.7 KiB
C#
250 lines
5.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Configuration.Install;
|
|
using System.Reflection;
|
|
using System.ServiceModel;
|
|
using System.ServiceProcess;
|
|
|
|
namespace Roblox.ServiceProcess;
|
|
|
|
public class ServiceHostApp<TServiceClass> : ServiceBasePublic where TServiceClass : class
|
|
{
|
|
private ServiceHost serviceHost;
|
|
|
|
private TServiceClass singleton;
|
|
|
|
private ServiceBasePublic[] otherSingletons;
|
|
|
|
public event EventHandler HostClosed;
|
|
|
|
public event EventHandler HostClosing;
|
|
|
|
public event EventHandler HostFaulted;
|
|
|
|
public event EventHandler HostOpened;
|
|
|
|
public event EventHandler HostOpening;
|
|
|
|
public ServiceHostApp(TServiceClass singleton)
|
|
{
|
|
this.singleton = singleton;
|
|
}
|
|
|
|
public ServiceHostApp(TServiceClass singleton, ServiceBasePublic[] others)
|
|
: this(singleton)
|
|
{
|
|
otherSingletons = others;
|
|
}
|
|
|
|
public ServiceHostApp()
|
|
{
|
|
}
|
|
|
|
protected override void OnStart(string[] args)
|
|
{
|
|
CloseServiceHost();
|
|
if (singleton != null)
|
|
{
|
|
serviceHost = new ServiceHost(singleton);
|
|
}
|
|
else
|
|
{
|
|
serviceHost = new ServiceHost(typeof(TServiceClass));
|
|
}
|
|
if (serviceHost.SingletonInstance is IArgumentService)
|
|
{
|
|
(serviceHost.SingletonInstance as IArgumentService).ProcessArgs(args);
|
|
}
|
|
serviceHost.Closed += serviceHost_Closed;
|
|
serviceHost.Closing += serviceHost_Closing;
|
|
serviceHost.Faulted += serviceHost_Faulted;
|
|
serviceHost.Opened += serviceHost_Opened;
|
|
serviceHost.Opening += serviceHost_Opening;
|
|
serviceHost.Open();
|
|
if (otherSingletons != null)
|
|
{
|
|
ServiceBasePublic[] array = otherSingletons;
|
|
foreach (ServiceBasePublic sbp in array)
|
|
{
|
|
sbp.OnStartPublic(args);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CloseServiceHost()
|
|
{
|
|
if (serviceHost != null)
|
|
{
|
|
if (serviceHost.State != CommunicationState.Closed)
|
|
{
|
|
serviceHost.Close();
|
|
}
|
|
serviceHost.Closed -= serviceHost_Closed;
|
|
serviceHost.Closing -= serviceHost_Closing;
|
|
serviceHost.Faulted -= serviceHost_Faulted;
|
|
serviceHost.Opened -= serviceHost_Opened;
|
|
serviceHost.Opening -= serviceHost_Opening;
|
|
serviceHost = null;
|
|
}
|
|
}
|
|
|
|
private void serviceHost_Closed(object sender, EventArgs e)
|
|
{
|
|
if (this.HostClosed != null)
|
|
{
|
|
this.HostClosed(sender, e);
|
|
}
|
|
}
|
|
|
|
private void serviceHost_Closing(object sender, EventArgs e)
|
|
{
|
|
if (this.HostClosing != null)
|
|
{
|
|
this.HostClosing(sender, e);
|
|
}
|
|
}
|
|
|
|
private void serviceHost_Faulted(object sender, EventArgs e)
|
|
{
|
|
if (this.HostFaulted != null)
|
|
{
|
|
this.HostFaulted(sender, e);
|
|
}
|
|
}
|
|
|
|
private void serviceHost_Opened(object sender, EventArgs e)
|
|
{
|
|
if (this.HostOpened != null)
|
|
{
|
|
this.HostOpened(sender, e);
|
|
}
|
|
}
|
|
|
|
private void serviceHost_Opening(object sender, EventArgs e)
|
|
{
|
|
if (this.HostOpening != null)
|
|
{
|
|
this.HostOpening(sender, e);
|
|
}
|
|
}
|
|
|
|
protected override void OnStop()
|
|
{
|
|
CloseServiceHost();
|
|
if (otherSingletons != null)
|
|
{
|
|
ServiceBasePublic[] array = otherSingletons;
|
|
foreach (ServiceBasePublic sbp in array)
|
|
{
|
|
sbp.OnStopPublic();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Process(string[] args)
|
|
{
|
|
Process(args, null);
|
|
}
|
|
|
|
public void Process(string[] args, Action statsTask)
|
|
{
|
|
if (args.Length != 0)
|
|
{
|
|
try
|
|
{
|
|
switch (args[0].Substring(1).ToLower())
|
|
{
|
|
case "console":
|
|
{
|
|
ConsoleKey closeSocketsKey = ConsoleKey.Q;
|
|
ConsoleKey exitKey = ConsoleKey.Escape;
|
|
ConsoleKey garbageCollectionKey = ConsoleKey.G;
|
|
Console.WriteLine("Starting {0}...", typeof(TServiceClass));
|
|
OnStart(args);
|
|
Console.WriteLine("Service started. Press any key to {0}.", (statsTask == null) ? "exit" : "get stats");
|
|
Console.WriteLine("Press {0} to force a full Garbage Collection cycle", garbageCollectionKey);
|
|
Console.WriteLine("Press {0} to close sockets or {1} to exit process", closeSocketsKey, exitKey);
|
|
while (true)
|
|
{
|
|
ConsoleKey key = Console.ReadKey(intercept: true).Key;
|
|
if (key == exitKey)
|
|
{
|
|
break;
|
|
}
|
|
if (key == garbageCollectionKey)
|
|
{
|
|
Console.Write("Initiating GC cycle ....");
|
|
GC.Collect(3, GCCollectionMode.Forced);
|
|
Console.WriteLine("done");
|
|
}
|
|
else if (key == closeSocketsKey)
|
|
{
|
|
Console.Write("Closing sockets....");
|
|
CloseServiceHost();
|
|
Console.WriteLine(" done");
|
|
Console.WriteLine("Press {0} to exit process", exitKey);
|
|
}
|
|
else
|
|
{
|
|
if (statsTask == null)
|
|
{
|
|
break;
|
|
}
|
|
statsTask();
|
|
}
|
|
}
|
|
Console.WriteLine("Stopping Service.");
|
|
OnStop();
|
|
break;
|
|
}
|
|
case "install":
|
|
{
|
|
Console.WriteLine("Installing...");
|
|
AssemblyInstaller installer2 = new AssemblyInstaller(Assembly.GetEntryAssembly(), new string[0]);
|
|
installer2.UseNewContext = true;
|
|
IDictionary savedState2 = new Hashtable();
|
|
installer2.Install(savedState2);
|
|
installer2.Commit(savedState2);
|
|
Console.WriteLine("Service Installed");
|
|
break;
|
|
}
|
|
case "uninstall":
|
|
{
|
|
Console.WriteLine("Uninstalling...");
|
|
AssemblyInstaller installer = new AssemblyInstaller(Assembly.GetEntryAssembly(), new string[0]);
|
|
installer.UseNewContext = true;
|
|
IDictionary savedState = new Hashtable();
|
|
installer.Uninstall(savedState);
|
|
Console.WriteLine("Service Uninstalled");
|
|
break;
|
|
}
|
|
default:
|
|
throw new ApplicationException("Bad argument " + args[0]);
|
|
}
|
|
return;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e.ToString());
|
|
return;
|
|
}
|
|
}
|
|
if (otherSingletons != null)
|
|
{
|
|
ServiceBase[] hosts = new ServiceBase[otherSingletons.Length + 1];
|
|
int pos = 0;
|
|
hosts[pos++] = this;
|
|
ServiceBasePublic[] array = otherSingletons;
|
|
foreach (ServiceBase sb in array)
|
|
{
|
|
hosts[pos++] = sb;
|
|
}
|
|
ServiceBase.Run(hosts);
|
|
}
|
|
else
|
|
{
|
|
ServiceBase.Run(this);
|
|
}
|
|
}
|
|
}
|