纵有疾风起
人生不言弃

C#开发可以可视化操作的windows服务

使用C#开发自定义windows服务是一件十分简单的事。那么什么时候,我们需要自己开发windows服务呢,就是当我们需要计算机定期或者一 直执行我们开发的某些程序的时候。我经常看到许多人开发的windows服务安装卸载都是使用cmd命令来进行的,我觉得这样的话,部署起来比较麻烦,于是就考虑做了一个可视化的windows控制程序,方便,快捷。

     这里我以一个WCF的监听服务为例,因为我是做一个局域聊天室,需要服务器端监听终端,所以我就开发了一个服务,以便控制此监听服务。然而,我们开发的windows服务,默认情况下是无法可视化的操作的,这里我就额外的开发一个工具来对此服务进行操作,效果图如下:
C#开发可以可视化操作的windows服务插图

开发步骤

1、“新建项目”——“Window服务”
C#开发可以可视化操作的windows服务插图1
Program.cs代码:

    using System;      using System.Collections.Generic;      using System.Linq;      using System.Text;      using System.ServiceModel;      using System.ServiceModel.Description;      using System.ServiceProcess;            namespace MSMQChatService      {          class Program          {              static void Main()              {                  #region 服务启动入口,正式用                        ServiceBase[] ServicesToRun;                  ServicesToRun = new ServiceBase[] {  new MQChatService()  };                  ServiceBase.Run(ServicesToRun);                       #endregion              }          }  

MQChatService.cs代码如下:

    protected override void OnStart(string[] args)              {                  //开启服务  这里就是你想要让服务做的操作                  StartService();              }  

3、切换到MQChatService的可视化界面
C#开发可以可视化操作的windows服务插图2

4、在可视化界面,单击鼠标右键,
C#开发可以可视化操作的windows服务插图3

将会出现一个Installer为后缀的新界面,默认好像是Project Installer.cs,我这里将其重命名为ServiceInstaller.cs
C#开发可以可视化操作的windows服务插图4

分别对界面上这两个组件进行属性配置,具体的属性签名可以查看属性面板的最下面(右下角处)

C#开发可以可视化操作的windows服务插图5

好了,我们的windows服务已经开发好了,接下来就开发一个可视化的控制器,来控制服务的安装、卸载、启动和停止。

1、  新建一个windows程序,名称ServiceSetup,Form1重命名为FrmServiceSetup,
C#开发可以可视化操作的windows服务插图6

界面控件如下:

C#开发可以可视化操作的windows服务插图7

Program.cs代码如下:

C#开发可以可视化操作的windows服务插图8

    using System;      using System.Collections.Generic;      using System.Diagnostics;      using System.Linq;      using System.Threading;      using System.Threading.Tasks;      using System.Windows.Forms;            namespace ServiceSetup      {          static class Program          {              /// <summary>              /// 应用程序的主入口点。              /// </summary>              [STAThread]              static void Main()              {                   //获取欲启动进程名                  string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;                  ////获取版本号                  //CommonData.VersionNumber = Application.ProductVersion;                  //检查进程是否已经启动,已经启动则显示报错信息退出程序。                  if (System.Diagnostics.Process.GetProcessesByName(strProcessName).Length > 1)                  {                      MessageBox.Show("程序已经运行。");                      Thread.Sleep(1000);                      System.Environment.Exit(1);                  }                  else                  {                      Application.EnableVisualStyles();                      Application.SetCompatibleTextRenderingDefault(false);                      Application.Run(new FrmServiceSetup());                  }              }          }      }  

View Code

主界面代码:

C#开发可以可视化操作的windows服务插图10

    using System;      using System.Collections.Generic;      using System.ComponentModel;      using System.Data;      using System.Drawing;      using System.Linq;      using System.Text;      using System.Threading.Tasks;      using System.Windows.Forms;            namespace ServiceSetup      {          public partial class FrmServiceSetup : Form          {              string strServiceName = string.Empty;              public FrmServiceSetup()              {                  InitializeComponent();                  strServiceName = string.IsNullOrEmpty(lblServiceName.Text) ? "MSMQChatService" : lblServiceName.Text;                  InitControlStatus(strServiceName, btnInstallOrUninstall, btnStartOrEnd, btnGetStatus, lblMsg, gbMain);              }                    /// <summary>              /// 初始化控件状态              /// </summary>              /// <param name="serviceName">服务名称</param>              /// <param name="btn1">安装按钮</param>              /// <param name="btn2">启动按钮</param>              /// <param name="btn3">获取状态按钮</param>              /// <param name="txt">提示信息</param>              /// <param name="gb">服务所在组合框</param>              void InitControlStatus(string serviceName, Button btn1, Button btn2, Button btn3, Label txt, GroupBox gb)              {                  try                  {                      btn1.Enabled = true;                            if (ServiceAPI.isServiceIsExisted(serviceName))                      {                          btn3.Enabled = true;                          btn2.Enabled = true;                          btn1.Text = "卸载服务";                          int status = ServiceAPI.GetServiceStatus(serviceName);                          if (status == 4)                          {                              btn2.Text = "停止服务";                          }                          else                          {                              btn2.Text = "启动服务";                          }                          GetServiceStatus(serviceName, txt);                          //获取服务版本                          string temp = string.IsNullOrEmpty(ServiceAPI.GetServiceVersion(serviceName)) ? string.Empty : "(" + ServiceAPI.GetServiceVersion(serviceName) + ")";                          gb.Text += temp;                      }                      else                      {                          btn1.Text = "安装服务";                          btn2.Enabled = false;                          btn3.Enabled = false;                          txt.Text = "服务【" + serviceName + "】未安装!";                      }                  }                  catch (Exception ex)                  {                      txt.Text = "error";                      LogAPI.WriteLog(ex.Message);                  }              }                    /// <summary>              /// 安装或卸载服务              /// </summary>              /// <param name="serviceName">服务名称</param>              /// <param name="btnSet">安装、卸载</param>              /// <param name="btnOn">启动、停止</param>              /// <param name="txtMsg">提示信息</param>              /// <param name="gb">组合框</param>              void SetServerce(string serviceName, Button btnSet, Button btnOn, Button btnShow, Label txtMsg, GroupBox gb)              {                  try                  {                      string location = System.Reflection.Assembly.GetExecutingAssembly().Location;                      string serviceFileName = location.Substring(0, location.LastIndexOf('\\')) + "\\" + serviceName + ".exe";                            if (btnSet.Text == "安装服务")                      {                          ServiceAPI.InstallmyService(null, serviceFileName);                          if (ServiceAPI.isServiceIsExisted(serviceName))                          {                              txtMsg.Text = "服务【" + serviceName + "】安装成功!";                              btnOn.Enabled = btnShow.Enabled = true;                              string temp = string.IsNullOrEmpty(ServiceAPI.GetServiceVersion(serviceName)) ? string.Empty : "(" + ServiceAPI.GetServiceVersion(serviceName) + ")";                              gb.Text += temp;                              btnSet.Text = "卸载服务";                              btnOn.Text = "启动服务";                          }                          else                          {                              txtMsg.Text = "服务【" + serviceName + "】安装失败,请检查日志!";                          }                      }                      else                      {                          ServiceAPI.UnInstallmyService(serviceFileName);                          if (!ServiceAPI.isServiceIsExisted(serviceName))                          {                              txtMsg.Text = "服务【" + serviceName + "】卸载成功!";                              btnOn.Enabled = btnShow.Enabled = false;                              btnSet.Text = "安装服务";                              //gb.Text =strServiceName;                          }                          else                          {                              txtMsg.Text = "服务【" + serviceName + "】卸载失败,请检查日志!";                          }                      }                  }                  catch (Exception ex)                  {                      txtMsg.Text = "error";                      LogAPI.WriteLog(ex.Message);                  }              }                    //获取服务状态              void GetServiceStatus(string serviceName, Label txtStatus)              {                  try                  {                      if (ServiceAPI.isServiceIsExisted(serviceName))                      {                          string statusStr = "";                          int status = ServiceAPI.GetServiceStatus(serviceName);                          switch (status)                          {                              case 1:                                  statusStr = "服务未运行!";                                  break;                              case 2:                                  statusStr = "服务正在启动!";                                  break;                              case 3:                                  statusStr = "服务正在停止!";                                  break;                              case 4:                                  statusStr = "服务正在运行!";                                  break;                              case 5:                                  statusStr = "服务即将继续!";                                  break;                              case 6:                                  statusStr = "服务即将暂停!";                                  break;                              case 7:                                  statusStr = "服务已暂停!";                                  break;                              default:                                  statusStr = "未知状态!";                                  break;                          }                          txtStatus.Text = statusStr;                      }                      else                      {                          txtStatus.Text = "服务【" + serviceName + "】未安装!";                      }                  }                  catch (Exception ex)                  {                      txtStatus.Text = "error";                      LogAPI.WriteLog(ex.Message);                  }              }                    //启动服务              void OnService(string serviceName, Button btn, Label txt)              {                  try                  {                      if (btn.Text == "启动服务")                      {                          ServiceAPI.RunService(serviceName);                                int status = ServiceAPI.GetServiceStatus(serviceName);                          if (status == 2 || status == 4 || status == 5)                          {                              txt.Text = "服务【" + serviceName + "】启动成功!";                              btn.Text = "停止服务";                          }                          else                          {                              txt.Text = "服务【" + serviceName + "】启动失败!";                          }                      }                      else                      {                          ServiceAPI.StopService(serviceName);                                int status = ServiceAPI.GetServiceStatus(serviceName);                          if (status == 1 || status == 3 || status == 6 || status == 7)                          {                              txt.Text = "服务【" + serviceName + "】停止成功!";                              btn.Text = "启动服务";                          }                          else                          {                              txt.Text = "服务【" + serviceName + "】停止失败!";                          }                      }                  }                  catch (Exception ex)                  {                      txt.Text = "error";                      LogAPI.WriteLog(ex.Message);                  }              }                    //安装or卸载服务              private void btnInstallOrUninstall_Click(object sender, EventArgs e)              {                  btnInstallOrUninstall.Enabled = false;                  SetServerce(strServiceName, btnInstallOrUninstall, btnStartOrEnd, btnGetStatus, lblMsg, gbMain);                  btnInstallOrUninstall.Enabled = true;                  btnInstallOrUninstall.Focus();              }                    //启动or停止服务              private void btnStartOrEnd_Click(object sender, EventArgs e)              {                  btnStartOrEnd.Enabled = false;                  OnService(strServiceName, btnStartOrEnd, lblMsg);                  btnStartOrEnd.Enabled = true;                  btnStartOrEnd.Focus();              }                    //获取服务状态              private void btnGetStatus_Click(object sender, EventArgs e)              {                  btnGetStatus.Enabled = false;                  GetServiceStatus(strServiceName, lblMsg);                  btnGetStatus.Enabled = true;                  btnGetStatus.Focus();              }                    private void FrmServiceSetup_Resize(object sender, EventArgs e)              {                  if (this.WindowState == FormWindowState.Minimized)    //最小化到系统托盘                  {                      notifyIcon1.Visible = true;    //显示托盘图标                      this.ShowInTaskbar = false;                      this.Hide();    //隐藏窗口                  }              }                    private void FrmServiceSetup_FormClosing(object sender, FormClosingEventArgs e)              {                  DialogResult result = MessageBox.Show("是缩小到托盘?", "确认", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);                  if (result== DialogResult.Yes)                  {                      // 取消关闭窗体                      e.Cancel = true;                      // 将窗体变为最小化                      this.WindowState = FormWindowState.Minimized;                  }                  else if (result == DialogResult.No)                  {                      System.Environment.Exit(0);                  }                  else                  {                      e.Cancel = true;                  }              }                    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)              {                  if (e.Button == MouseButtons.Left&&this.WindowState == FormWindowState.Minimized)                  {                          this.Show();                          this.WindowState = FormWindowState.Normal;                          this.ShowInTaskbar = true; //显示在系统任务栏                           //notifyIcon1.Visible = false; //托盘图标不可见                           this.Activate();                  }              }                    private void 打开主界面ToolStripMenuItem_Click(object sender, EventArgs e)              {                  this.Show();                  this.WindowState = FormWindowState.Normal;                  this.ShowInTaskbar = true; //显示在系统任务栏                   notifyIcon1.Visible = false; //托盘图标不可见                   this.Activate();              }                    private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)              {                  System.Environment.Exit(0);                    ExitProcess();              }                 //结束进程              private void ExitProcess()              {                  System.Environment.Exit(0);                  Process[] ps = Process.GetProcesses();                  foreach (Process item in ps)                  {                      if (item.ProcessName == "ServiceSetup")                      {                          item.Kill();                      }                  }              }       }      }  

View Code

新建一个类,专门用于日志操作LogAPI.cs,这里的日志路径和名称建议从配置文件中读取

C#开发可以可视化操作的windows服务插图12

 using System;      using System.Collections.Generic;      using System.IO;      using System.Linq;      using System.Text;      using System.Threading.Tasks;            namespace ServiceSetup      {          public class LogAPI          {              private static string myPath = "";              private static string myName = "";                    /// <summary>              /// 初始化日志文件              /// </summary>              /// <param name="logPath"></param>              /// <param name="logName"></param>              public static void InitLogAPI(string logPath, string logName)              {                  myPath = logPath;                  myName = logName;              }                    /// <summary>              /// 写入日志              /// </summary>              /// <param name="ex">日志信息</param>              public static void WriteLog(string ex)              {                  if (myPath == "" || myName == "")                      return;                        string Year = DateTime.Now.Year.ToString();                  string Month = DateTime.Now.Month.ToString().PadLeft(2, '0');                  string Day = DateTime.Now.Day.ToString().PadLeft(2, '0');                        //年月日文件夹是否存在,不存在则建立                  if (!Directory.Exists(myPath + "\\LogFiles\\" + Year + "_" + Month + "\\" + Year + "_" + Month + "_" + Day))                  {                      Directory.CreateDirectory(myPath + "\\LogFiles\\" + Year + "_" + Month + "\\" + Year + "_" + Month + "_" + Day);                  }                        //写入日志UNDO,Exception has not been handle                  string LogFile = myPath + "\\LogFiles\\" + Year + "_" + Month + "\\" + Year + "_" + Month + "_" + Day + "\\" + myName;                  if (!File.Exists(LogFile))                  {                      System.IO.StreamWriter myFile;                      myFile = System.IO.File.AppendText(LogFile);                      myFile.Close();                  }                        while (true)                  {                      try                      {                          StreamWriter sr = File.AppendText(LogFile);                          sr.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "  " + ex);                          sr.Close();                          break;                      }                      catch (Exception e)                      {                          System.Threading.Thread.Sleep(50);                          continue;                      }                  }                    }                }      }  

View Code

Windows服务的操作类ServiceAPI.cs

C#开发可以可视化操作的windows服务插图14

    using System;      using System.Collections;      using System.Collections.Generic;      using System.Configuration.Install;      using System.IO;      using System.Linq;      using System.Reflection;      using System.ServiceProcess;      using System.Text;      using System.Threading.Tasks;      using Microsoft.Win32;            namespace ServiceSetup      {          public class ServiceAPI          {              /// <summary>              /// 检查服务存在的存在性              /// </summary>              /// <param name=" NameService ">服务名</param>              /// <returns>存在返回 true,否则返回 false;</returns>              public static bool isServiceIsExisted(string NameService)              {                  ServiceController[] services = ServiceController.GetServices();                  foreach (ServiceController s in services)                  {                      if (s.ServiceName.ToLower() == NameService.ToLower())                      {                          return true;                      }                  }                  return false;              }              /// <summary>              /// 安装Windows服务              /// </summary>              /// <param name="stateSaver">集合</param>              /// <param name="filepath">程序文件路径</param>              public static void InstallmyService(IDictionary stateSaver, string filepath)              {                  AssemblyInstaller AssemblyInstaller1 = new AssemblyInstaller();                  AssemblyInstaller1.UseNewContext = true;                  AssemblyInstaller1.Path = filepath;                  AssemblyInstaller1.Install(stateSaver);                  AssemblyInstaller1.Commit(stateSaver);                  AssemblyInstaller1.Dispose();              }              /// <summary>              /// 卸载Windows服务              /// </summary>              /// <param name="filepath">程序文件路径</param>              public static void UnInstallmyService(string filepath)              {                  AssemblyInstaller AssemblyInstaller1 = new AssemblyInstaller();                  AssemblyInstaller1.UseNewContext = true;                  AssemblyInstaller1.Path = filepath;                  AssemblyInstaller1.Uninstall(null);                  AssemblyInstaller1.Dispose();              }                    /// <summary>              /// 启动服务              /// </summary>              /// <param name=" NameService ">服务名</param>              /// <returns>存在返回 true,否则返回 false;</returns>              public static bool RunService(string NameService)              {                  bool bo = true;                  try                  {                      ServiceController sc = new ServiceController(NameService);                      if (sc.Status.Equals(ServiceControllerStatus.Stopped) || sc.Status.Equals(ServiceControllerStatus.StopPending))                      {                          sc.Start();                      }                  }                  catch (Exception ex)                  {                      bo = false;                      LogAPI.WriteLog(ex.Message);                  }                        return bo;              }                    /// <summary>              /// 停止服务              /// </summary>              /// <param name=" NameService ">服务名</param>              /// <returns>存在返回 true,否则返回 false;</returns>              public static bool StopService(string NameService)              {                  bool bo = true;                  try                  {                      ServiceController sc = new ServiceController(NameService);                      if (!sc.Status.Equals(ServiceControllerStatus.Stopped))                      {                          sc.Stop();                      }                  }                  catch (Exception ex)                  {                      bo = false;                      LogAPI.WriteLog(ex.Message);                  }                        return bo;              }                    /// <summary>              /// 获取服务状态              /// </summary>              /// <param name=" NameService ">服务名</param>              /// <returns>返回服务状态</returns>              public static int GetServiceStatus(string NameService)              {                  int ret = 0;                  try                  {                      ServiceController sc = new ServiceController(NameService);                      ret = Convert.ToInt16(sc.Status);                  }                  catch (Exception ex)                  {                      ret = 0;                      LogAPI.WriteLog(ex.Message);                  }                        return ret;              }                    /// <summary>              /// 获取服务安装路径              /// </summary>              /// <param name="ServiceName"></param>              /// <returns></returns>              public static string GetWindowsServiceInstallPath(string ServiceName)              {                  string path = "";                  try                  {                      string key = @"SYSTEM\CurrentControlSet\Services\" + ServiceName;                      path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();                            path = path.Replace("\"", string.Empty);//替换掉双引号                              FileInfo fi = new FileInfo(path);                      path = fi.Directory.ToString();                  }                  catch (Exception ex)                  {                      path = "";                      LogAPI.WriteLog(ex.Message);                  }                  return path;              }                    /// <summary>              /// 获取指定服务的版本号              /// </summary>              /// <param name="serviceName">服务名称</param>              /// <returns></returns>              public static string GetServiceVersion(string serviceName)              {                  if (string.IsNullOrEmpty(serviceName))                  {                      return string.Empty;                  }                  try                  {                      string path = GetWindowsServiceInstallPath(serviceName) + "\\" + serviceName + ".exe";                      Assembly assembly = Assembly.LoadFile(path);                      AssemblyName assemblyName = assembly.GetName();                      Version version = assemblyName.Version;                      return version.ToString();                  }                  catch (Exception ex)                  {                      LogAPI.WriteLog(ex.Message);                      return string.Empty;                  }              }          }      }  

View Code

注意:记得将服务程序的dll拷贝到可视化安装程序的bin目录下面。包括配置文件。如果运行报错,尝试以管理员身份运行安装程序。

文章转载于:https://www.cnblogs.com/jiekzou/p/4393886.html

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » C#开发可以可视化操作的windows服务
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录