using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration.Install; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.ServiceProcess; using Telerik.WinControls; using Telerik.WinControls.UI; using System.Diagnostics; using Microsoft.Win32; using System.Xml; using System.Drawing.Imaging; using System.Drawing.Text; using System.Collections; using System.IO; using System.Security.AccessControl; using System.Security.Principal; namespace ServiceConfigurator { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private string SERVICE_NAME = null; const string userRoot = "HKEY_LOCAL_MACHINE"; const string subkey = "SYSTEM\\CurrentControlSet\\services"; const string keyName = userRoot + "\\" + subkey; //private data private string _configFilename = ""; private bool _isDirty; private bool IsDirty { get { return _isDirty; } set { _isDirty = value; } } private Hashtable serviceHT = new Hashtable(); private string tcpServerServiceName = "TCPServerService"; private string tcpClientServiceName = "TCPClientService"; //static string logFile = System.AppDomain.CurrentDomain.BaseDirectory + "\\log.log"; //public properties public virtual string ConfigFilename { get { return _configFilename; } set { _configFilename = value; } } private void btnStart_Click(object sender, EventArgs e) { StartService(SERVICE_NAME,1000); } private void btnRestart_Click(object sender, EventArgs e) { RestartService(SERVICE_NAME, 1000); } private void btnStop_Click(object sender, EventArgs e) { StopService(SERVICE_NAME, 2000); lblInfoStatus.Text = ""; } private void btnCheckService_Click(object sender, EventArgs e) { UpdateStatus(); } public static void StartService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); } catch { // ... } } public static void RestartService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { int millisec1 = Environment.TickCount; TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); // count the rest of the timeout int millisec2 = Environment.TickCount; timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1)); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); } catch { // ... } } public static void StopService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); } catch { // ... } } string GetStatus(string serviceName) { ServiceController sc = new ServiceController(serviceName); try { switch (sc.Status) { case ServiceControllerStatus.Running: return "Running "; case ServiceControllerStatus.Stopped: return "Stopped "; case ServiceControllerStatus.Paused: return "Paused "; case ServiceControllerStatus.StopPending: return "Stopping "; case ServiceControllerStatus.StartPending: return "Starting "; default: return "Status Changing "; } } catch { return "Invalid Service name!"; } } string GetPath(string serviceName) { string fullKeyName = keyName + "\\" + txtServiceName.Text; string path = (string)Registry.GetValue(fullKeyName, "ImagePath", "Not available ..."); if (path != null) { if(path.Substring(0,1) == "\"") path = path.Substring(1, path.Length - 2); } return path; } private void txtServiceName_TextChanged(object sender, EventArgs e) { Checkstate(); } private void Checkstate() { foreach (Control ctrl in this.Controls) { if (ctrl is RadGroupBox) { foreach (Control tb in ctrl.Controls) { if (tb is RadButton) { ((RadButton)tb).Enabled = (txtServiceName.Text.Length > 0); } } } } btnRefesh.Enabled = true; SERVICE_NAME = txtServiceName.Text.ToString(); } private void Form1_Load(object sender, EventArgs e) { //#region Folder Rights //try //{ // GrantAccess(logFile); //} //catch //{ // lblInfoStatus.Text = "Unable to give file permissions. Please run as admin!"; //} //#endregion //GetAllServices(); lblInfoStatus.Text = ""; Checkstate(); timerStatus.Start(); timerServiceState.Start(); LoadServices(); GetAllServices(); ToolTip toolTip1 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnStart, "START"); ToolTip toolTip2 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnRestart, "RESTART"); ToolTip toolTip3 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnStop, "STOP"); ToolTip toolTip4 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnSave, "SAVE"); ToolTip toolTip5 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnClose, "CLOSE"); ToolTip toolTip6 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnUninstall, "UNINSTALL"); ToolTip toolTip7 = new System.Windows.Forms.ToolTip(); toolTip1.SetToolTip(btnRefesh, "REFRESH LIST"); } private void UpdateStatus() { //long times = DateTime.Now.Ticks; //int pointNb = 0; //if (times % 5 == 0) pointNb = 5; //else if (times % 4 == 0) pointNb = 4; //else if (times % 3 == 0) pointNb = 3; //else if (times % 2 == 0) pointNb = 2; //else if (times % 1 == 0) pointNb = 1; //string points = new String('.', pointNb); lblStatus.Text = GetStatus(SERVICE_NAME); // +points; txtPath.Text = GetPath(SERVICE_NAME); #region Notify icon if (!Program.notify) return; if (!serviceHT.Contains(SERVICE_NAME)) serviceHT.Add(SERVICE_NAME, lblStatus.Text); else { if(serviceHT[SERVICE_NAME].ToString() != lblStatus.Text) { //add notify status changed for service notifyIcon1.BalloonTipText = string.Format("{0} is {1}", SERVICE_NAME, lblStatus.Text); notifyIcon1.Visible = true; notifyIcon1.ShowBalloonTip(500); serviceHT[SERVICE_NAME] = lblStatus.Text; } } #endregion } private void NotifyUserIfChanged() { } private void timerStatus_Tick(object sender, EventArgs e) { if(txtServiceName.Text !="") UpdateStatus(); NotifyUserIfChanged(); //pictureBox1.Visible = lblStatus.Text.Equals("Running "); //if (txtServiceName.Text != "") //{ // btnUninstall.Enabled = !(lblStatus.Text.Equals("Running ")); //} //else btnUninstall.Enabled = false; lblProcNo.Text = CheckProcesses(); } AutoCompleteStringCollection colValues = new AutoCompleteStringCollection(); private void GetAllServices() { // get list of Windows services ServiceController[] services = ServiceController.GetServices(); List ac = new List(); // try to find service name foreach (ServiceController service in services) { ac.Add(service.ServiceName.ToString()); } colValues.AddRange(ac.ToArray()); if (colValues.Contains(tcpServerServiceName)) txtServiceName.Text = tcpServerServiceName; else if (colValues.Contains(tcpClientServiceName)) txtServiceName.Text = tcpClientServiceName; } private void LoadPropertyGrid() { try { string[] splitConfig = txtPath.Text.Split(new string[] { ".exe" }, StringSplitOptions.None); ConfigFilename = splitConfig[0] + ".exe.Config"; if (System.IO.File.Exists(ConfigFilename)) { this.propertyGrid1.SelectedObject = LoadConfiguration(ConfigFilename); } else this.propertyGrid1.SelectedObject = null; //Process.Start("notepad.exe", fileConfig); } catch { } } private void btnClose_Click(object sender, EventArgs e) { if (this.IsDirty == true) { DialogResult result = RadMessageBox.Show("Save Application Configuration changes before closing?", "Application Configuration", MessageBoxButtons.YesNoCancel, RadMessageIcon.Question); if (result == DialogResult.Yes) { try { SaveConfiguration(this.ConfigFilename, (CustomClass)this.propertyGrid1.SelectedObject); RadMessageBox.Show("Application Configuration changes have been saved.", "Application Configuration", MessageBoxButtons.OK, RadMessageIcon.Info); this.Close(); } catch (Exception ex) { RadMessageBox.Show("Failed to btnSave configuration. Reason(" + ex.Message + ")", "Application Configuration", MessageBoxButtons.OK, RadMessageIcon.Exclamation); } } else if (result == DialogResult.No) { this.Close(); } } else { this.Close(); } } public CustomClass LoadConfiguration(string configurationFile) { CustomClass customClass = new CustomClass(); try { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(configurationFile); XmlNode configuration = xmlDoc.SelectSingleNode("configuration"); //Build the node list XmlNodeList sectionList = configuration.ChildNodes; for (int y = 0; y < sectionList.Count; y++) { XmlNodeList settingsList = xmlDoc.SelectNodes("configuration/" + sectionList[y].Name + "/add"); if (settingsList.Count != 0 && settingsList != null) { //Add a property to customClass for each node found. for (int i = 0; i < settingsList.Count; i++) { XmlAttribute atrribKey = settingsList[i].Attributes["key"]; XmlAttribute attribValue = settingsList[i].Attributes["value"]; XmlAttribute attribDescription = settingsList[i].Attributes["description"]; if (atrribKey != null && attribValue != null) { //If there's no description for the key - assign the name to the description. //The description attribute is displayed below the name in the property grid. if (attribDescription == null) { attribDescription = atrribKey; } //We'll at least test to see if it's a boolean property and set the type here //to force the property grid to display a dropdown list of True or False. Type propType; if (attribValue.Value.ToLower() == "true" || attribValue.Value.ToLower() == "false") { propType = typeof(System.Boolean); } else { propType = typeof(System.String); } //Now add the property customClass.AddProperty(atrribKey.Value.ToString(), attribValue.Value.ToString(), attribDescription.Value.ToString(), sectionList[y].Name, propType, false, false); } } } } xmlDoc = null; } catch (Exception ex) { throw ex; } return customClass; } public void SaveConfiguration(string configurationFile, CustomClass customClass) { try { //Reload the configuration file XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(configurationFile); //Save a backup version xmlDoc.Save(configurationFile + "_bak"); //Populate our property collection. PropertyDescriptorCollection props = customClass.GetProperties(); //Repolulate the three supported sections RepopulateXmlSection("ApplicationConfiguration", xmlDoc, props); RepopulateXmlSection("CommonConfiguration", xmlDoc, props); RepopulateXmlSection("appSettings", xmlDoc, props); xmlDoc.Save(configurationFile); } catch (Exception ex) { throw ex; } } private void RepopulateXmlSection(string sectionName, XmlDocument xmlDoc, PropertyDescriptorCollection props) { XmlNodeList nodes = xmlDoc.SelectNodes("configuration/" + sectionName + "/add"); for (int i = 0; i < nodes.Count; i++) { //Find the property in the property collection with the same name as the current node in the Xml document CustomClass.DynamicProperty property = (CustomClass.DynamicProperty)props[nodes[i].Attributes["key"].Value]; if (property != null) { //Set the node value to the property value (which will have been set in the Property grid. nodes[i].Attributes["value"].Value = property.GetValue(null).ToString(); //Check to see if we have a value for our extended custom xml attribute - the description attribute. //The default description is the property name when no descripyion attribute is present. //If they're not the same - then a value was passed when the property was created. if (property.Description != property.Name) { //double check here that there is in fact a description attribute if (nodes[i].Attributes["description"] != null) { nodes[i].Attributes["description"].Value = property.Description; } } } } } private void propertyGrid1_PropertyValueChanged(object sender, PropertyGridItemValueChangedEventArgs e) { this.IsDirty = true; } private void txtPath_TextChanged(object sender, EventArgs e) { LoadPropertyGrid(); } private void btnSave_Click(object sender, EventArgs e) { try { SaveConfiguration(ConfigFilename, (CustomClass)this.propertyGrid1.SelectedObject); RadMessageBox.Show("Application Configuration changes have been saved.", "Application Configuration", MessageBoxButtons.OK, RadMessageIcon.Info); this.IsDirty = false; this.propertyGrid1.Focus(); //if(lblStatus.Text=="Running") //{ StopService(SERVICE_NAME, 1000); StartService(SERVICE_NAME, 1000); //} } catch (Exception ex) { RadMessageBox.Show("Failed to btnSave configuration. Reason(" + ex.Message + ")", "Application Configuration", MessageBoxButtons.OK, RadMessageIcon.Exclamation); } } private void btnUninstall_Click(object sender, EventArgs e) { if (UninstallMe()) { RadMessageBox.Show("Successfully uninstalled the " + SERVICE_NAME, "Status", MessageBoxButtons.OK, RadMessageIcon.Info); colValues.Remove(txtServiceName.Text); txtServiceName.Text = ""; LoadServices(); } else { RadMessageBox.Show("Unsuccessfully uninstalled the " + SERVICE_NAME, "Status", MessageBoxButtons.OK, RadMessageIcon.Error); } } private bool UninstallMe() { try { ManagedInstallerClass.InstallHelper( new string[] { "/u", txtPath.Text }); } catch { return false; } return true; } private void LoadServices() { txtServiceName.AutoCompleteMode = AutoCompleteMode.Suggest; txtServiceName.AutoCompleteSource = AutoCompleteSource.CustomSource; txtServiceName.AutoCompleteCustomSource = colValues; } private void btnRefesh_Click(object sender, EventArgs e) { colValues.Clear(); GetAllServices(); LoadServices(); } private string CheckProcesses() { int numberOfProcesses = 0; Process[] processes = Process.GetProcesses(); foreach (Process process in processes) { numberOfProcesses++; } return numberOfProcesses.ToString(); } private void ResizeForm(object sender, EventArgs e) { this.Height = radCollapsiblePanel1.Location.Y + radCollapsiblePanel1.Height +43; } //private void timerServiceState_Tick(object sender, EventArgs e) //{ // if (File.Exists(logFile) && lblStatus.Text != ServiceControllerStatus.Stopped.ToString()) // { // lblInfoStatus.Text = File.ReadAllText(logFile); // } //} private bool GrantAccess(string fullPath) { if (!File.Exists(fullPath)) File.Create(fullPath); DirectoryInfo dInfo = new DirectoryInfo(fullPath); DirectorySecurity dSecurity = dInfo.GetAccessControl(); dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); dInfo.SetAccessControl(dSecurity); return true; } } }