Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'remotes/origin/BUG-4264-TVService_ignor…

…es_shutdown'
  • Loading branch information...
commit 62dda4359a776f45dfeea70e71f160c06babcd98 2 parents 5029157 + 3ccc969
@Sebastiii Sebastiii authored
Showing with 79 additions and 15 deletions.
  1. +79 −15 TvEngine3/TVLibrary/TvService/Service1.cs
View
94 TvEngine3/TVLibrary/TvService/Service1.cs
@@ -25,6 +25,7 @@
using System.Configuration;
using System.Configuration.Install;
using System.Diagnostics;
+using System.Reflection;
using System.Security.Principal;
using System.ServiceProcess;
using System.Threading;
@@ -49,11 +50,25 @@ public partial class Service1 : ServiceBase
private Thread _tvServiceThread = null;
private static Thread _unhandledExceptionInThread = null;
+ const int SERVICE_ACCEPT_PRESHUTDOWN = 0x100; // not supported on Windows XP
+ const int SERVICE_CONTROL_PRESHUTDOWN = 0xf; // not supported on Windows XP
+
/// <summary>
/// Initializes a new instance of the <see cref="Service1"/> class.
/// </summary>
public Service1()
{
+ if (Environment.OSVersion.Version.Major >= 6)
+ {
+ // Enable pre-shutdown notification by accessing the ServiceBase class's internals through .NET reflection (code by Siva Chandran P)
+ FieldInfo acceptedCommandsFieldInfo = typeof(ServiceBase).GetField("acceptedCommands", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (acceptedCommandsFieldInfo != null)
+ {
+ int value = (int)acceptedCommandsFieldInfo.GetValue(this);
+ acceptedCommandsFieldInfo.SetValue(this, value | SERVICE_ACCEPT_PRESHUTDOWN);
+ }
+ }
+
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
InitializeComponent();
}
@@ -107,7 +122,7 @@ private static void Main(string[] args)
ti.Installers.Add(mi);
String path = String.Format("/assemblypath={0}",
System.Reflection.Assembly.GetExecutingAssembly().Location);
- String[] cmdline = {path};
+ String[] cmdline = { path };
InstallContext ctx = new InstallContext("", cmdline);
ti.Context = ctx;
ti.Install(new Hashtable());
@@ -120,7 +135,7 @@ private static void Main(string[] args)
ti.Installers.Add(mi);
String path = String.Format("/assemblypath={0}",
System.Reflection.Assembly.GetExecutingAssembly().Location);
- String[] cmdline = {path};
+ String[] cmdline = { path };
InstallContext ctx = new InstallContext("", cmdline);
ti.Context = ctx;
ti.Uninstall(null);
@@ -131,7 +146,7 @@ private static void Main(string[] args)
if (opt != null && opt.ToUpperInvariant() == "/DEBUG")
{
Service1 s = new Service1();
- s.DoStart(new string[] {"/DEBUG"});
+ s.DoStart(new string[] { "/DEBUG" });
do
{
Thread.Sleep(100);
@@ -144,7 +159,8 @@ private static void Main(string[] args)
//
// ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
//
- ServiceBase[] ServicesToRun = new ServiceBase[] {new Service1()};
+ ServiceBase[] ServicesToRun = new ServiceBase[] { new Service1() };
+ ServicesToRun[0].CanShutdown = true; // Allow OnShutdown()
ServiceBase.Run(ServicesToRun);
}
@@ -282,11 +298,34 @@ protected override void OnStop()
_tvServiceThread = null;
}
}
+
+ /// <summary>
+ /// When implemented in a derived class, executes when the system is shutting down. Specifies what should occur immediately prior to the system shutting down.
+ /// </summary>
+ protected override void OnShutdown()
+ {
+ OnStop();
+ }
+
+ /// <summary>
+ /// When implemented in a derived class, executes when the Service Control Manager (SCM) passes a custom command to the service. Specifies actions to take when a command with the specified parameter value occurs.
+ /// </summary>
+ /// <param name="command"></param>
+ protected override void OnCustomCommand(int command)
+ {
+ // Check for pre-shutdown notification (code by Siva Chandran P)
+ if (command == SERVICE_CONTROL_PRESHUTDOWN)
+ {
+ OnStop();
+ }
+ else
+ base.OnCustomCommand(command);
+ }
}
public class TvServiceThread : IPowerEventHandler
{
- #region variables
+ #region variables
private EventWaitHandle _InitializedEvent;
private static bool _started;
@@ -661,7 +700,7 @@ private void StartRemoting()
try
{
// create the object reference and make the singleton instance available
- RemotingServices.Marshal(_controller, "TvControl", typeof (IController));
+ RemotingServices.Marshal(_controller, "TvControl", typeof(IController));
RemoteControl.Clear();
}
catch (Exception ex)
@@ -773,14 +812,21 @@ private void StopPlugins()
public void OnStop()
{
- if (!Started)
+ if (!_started)
return;
+
Log.WriteFile("TV Service: stopping");
+ // Reset "Global\MPTVServiceInitializedEvent"
if (_InitializedEvent != null)
{
_InitializedEvent.Reset();
}
+
+ // Stop the plugins
+ StopPlugins();
+
+ // Stop remoting and deinit the TvController
StopRemoting();
RemoteControl.Clear();
if (_controller != null)
@@ -789,7 +835,7 @@ public void OnStop()
_controller = null;
}
- StopPlugins();
+ // Terminate the power event thread
if (_powerEventThreadId != 0)
{
Log.Debug("TV Service: OnStop asking PowerEventThread to exit");
@@ -798,6 +844,7 @@ public void OnStop()
}
_powerEventThreadId = 0;
_powerEventThread = null;
+
_started = false;
Log.WriteFile("TV Service: stopped");
}
@@ -813,39 +860,56 @@ public void OnStart()
Thread.CurrentThread.Name = "TVService";
+ // Log TvService start and versions
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
-
Log.WriteFile("TVService v" + versionInfo.FileVersion + " is starting up on " +
- OSInfo.OSInfo.GetOSDisplayVersion());
+ OSInfo.OSInfo.GetOSDisplayVersion());
- //Check for unsupported operating systems
+ // Warn about unsupported operating systems
OSPrerequisites.OSPrerequisites.OsCheck(false);
+ // Start the power event thread
_powerEventThread = new Thread(PowerEventThread);
_powerEventThread.Name = "PowerEventThread";
_powerEventThread.IsBackground = true;
_powerEventThread.Start();
+
+ // Init the TvController and start remoting
_controller = new TVController();
_controller.Init();
+ StartRemoting();
+
+ // Start the plugins
StartPlugins();
- StartRemoting();
- _started = true;
+ // Set "Global\MPTVServiceInitializedEvent"
if (_InitializedEvent != null)
{
_InitializedEvent.Set();
}
+ _started = true;
Log.Info("TV service: Started");
+
+ // Wait for termination
while (true)
{
Thread.Sleep(1000);
}
}
}
+ catch (ThreadAbortException)
+ {
+ Log.Info("TvService is beeing stopped");
+ }
catch (Exception ex)
{
- //wait for thread to exit. eg. when stopping tvservice
- Log.Error("TvService OnStart failed : {0}", ex.ToString());
+ if (_started)
+ Log.Error("TvService terminated unexpectedly: {0}", ex.ToString());
+ else
+ Log.Error("TvService failed not start: {0}", ex.ToString());
+ }
+ finally
+ {
_started = true; // otherwise the onstop code will not complete.
OnStop();
}
Please sign in to comment.
Something went wrong with that request. Please try again.