using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.ServiceProcess; using System.Threading; using Microsoft.Win32; namespace RepoCleanup { /// ///

Cleanup Windows service. Creates a CleanupThread thread.

/// Methods modified: ///

Copyright (c) 2002 Alexis Grandemange
/// Mail: alexis.grandemange@pagebox.net

///
This program is free software; you can redistribute it and/or
	/// modify it under the terms of the GNU Lesser General Public
	/// License as published by the Free Software Foundation; version
	/// 2.1 of the License.
	/// This library is distributed in the hope that it will be useful,
	/// but WITHOUT ANY WARRANTY; without even the implied warranty of
	/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	/// GNU Lesser General Public License for more details.
	/// A copy of the GNU Lesser General Public License lesser.txt should be
	/// included in the distribution.
///
public class Cleanup : System.ServiceProcess.ServiceBase { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Wrapper thread object around CleanupThread /// private Thread cleanerThread; /// /// CleanupThread singleton /// private CleanupThread cleaner; public Cleanup() { // This call is required by the Windows.Forms Component Designer. InitializeComponent(); } // The main entry point for the process static void Main() { System.ServiceProcess.ServiceBase[] ServicesToRun; // More than one user Service may run within the same process. To add // another service to this process, change the following line to // create a second service object. For example, // // ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()}; // ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Cleanup() }; System.ServiceProcess.ServiceBase.Run(ServicesToRun); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); this.ServiceName = "Cleanup"; } #endregion /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } /// /// Reads the cleanup.xml full path from the startup parameters. /// Creates and starts CleanupThread. /// /// cleanup.xml path and debug mode protected override void OnStart(string[] args) { string cleanupPath = null; bool toLog = false; RegistryKey regKey = Registry.LocalMachine; regKey = regKey.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\Cleanup\\Parameters"); if (regKey != null) { cleanupPath = (string)regKey.GetValue("ConfigFile"); int iToLog = (int)regKey.GetValue("LogDebug"); if (iToLog == 1) toLog = true; regKey.Close(); } if (args.Length < 1) { if (cleanupPath == null) { CleanupThread.error( "Cleanup.OnStart service without startup parameter (cleanup.xml full path)"); return; } } else { cleanupPath = args[0]; if (args.Length == 2) { if (args[1].Equals("debug")) toLog = true; else toLog = false; } try { regKey = Registry.LocalMachine; regKey = regKey.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\Cleanup", true); regKey = regKey.CreateSubKey("Parameters"); regKey.SetValue("ConfigFile", cleanupPath); if (toLog) regKey.SetValue("LogDebug", (int)1); else regKey.SetValue("LogDebug", (int)0); } catch(System.Security.SecurityException se) { CleanupThread.error( "Cleanup.OnStart not allowed to update HKLM\\SYSTEM\\CurrentControlSet\\Services\\Cleanup " + se.Message); } } cleaner = new CleanupThread(cleanupPath, toLog); cleanerThread = new Thread(new ThreadStart(cleaner.ThreadRun)); try { cleanerThread.Start(); } catch (ThreadStateException e) { CleanupThread.error("Cleanup.OnStart " + e.Message); } catch (ThreadInterruptedException e) { CleanupThread.error("Cleanup.OnStart " + e.Message); } } /// /// Terminate CleanupThread thread. /// protected override void OnStop() { if (cleaner == null) return; try { lock(cleaner) { cleaner.toStop = true; Monitor.Pulse(cleaner); } cleanerThread.Join(); } catch (SynchronizationLockException e) { CleanupThread.error("Cleanup.OnStop " + e.Message); } catch (ThreadStateException e) { CleanupThread.error("Cleanup.OnStop " + e.Message); } catch (ThreadInterruptedException e) { CleanupThread.error("Cleanup.OnStop " + e.Message); } } } }