C#开发人员能够可视化操作windows服务
使用C#开发自己的定义windows服务是一个很简单的事。因此,当。我们需要发展自己windows它的服务。这是当我们需要有定期的计算机或运行某些程序的时候,我们开发。在这里,我有WCF监听案例,因为我是做本地聊天室。必须server结束监控终端,所以,我开发了一个服务。便控制此监听服务。
然而。我们开发的windows服务,默认情况下是无法可视化的操作的。这里我就额外的开发一个工具来对此服务进行操作,效果图例如以下:
开发步骤:
1、“新建项目”——“Window服务”

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的可视化界面

4、在可视化界面,单击鼠标右键,
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvem91eXVqaWUxMTI3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
将会出现一个Installer为后缀的新界面。默认好像是Project Installer.cs,我这里将其重命名为ServiceInstaller.cs
分别对界面上这两个组件进行属性配置,详细的属性签名能够查看属性面板的最以下(右下角处)
好了,我们的windows服务已经开发好了。接下来就开发一个可视化的控制器,来控制服务的安装、卸载、启动和停止。
1、 新建一个windows程序,名称ServiceSetup。Form1重命名为FrmServiceSetup,
界面控件例如以下:
Program.cs代码例如以下:
- 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());
- }
- }
- }
- }
主界面代码:
- 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">安装button</param>
- /// <param name="btn2">启动button</param>
- /// <param name="btn3">获取状态button</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();
- }
- }
- }
- }
- }
新建一个类,专门用于日志操作LogAPI.cs
- 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;
- }
- }
- }
- }
- }
Windows服务的操作类ServiceAPI.cs
- 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;
- }
- }
- }
- }
注意:记住服务程序dll复制到可视化的安装程序bin下面的文件夹。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
C#开发人员能够可视化操作windows服务的更多相关文章
- C# 操作windows服务[启动、停止、卸载、安装]
主要宗旨:不已命令形式操作windows服务 static void Main(string[] args) { var path = @"E:\开发辅助项目\WCF\WCF.Test\WC ...
- C#通过SC命令和静态公共类来操作Windows服务
调用的Windows服务应用程序网址:http://www.cnblogs.com/pingming/p/5115304.html 一.引用 二.公共静态类:可以单独放到类库里 using Syste ...
- cmd命令行和bat批处理操作windows服务(转载)
一.cmd命令行---进行Windows服务操作 1.安装服务 sc create 服务名 binPath= "C:\Users\Administrator\Desktop\win32srv ...
- C#.NET 操作Windows服务承载WCF
Windows服务的制作.安装可以参考这篇: C#.NET 操作Windows服务(安装.卸载) - runliuv - 博客园 (cnblogs.com) 本篇会在这个解决方案基础上,继续修改. 一 ...
- 开发便于运维的Windows服务
过去几个月,DevOps on Windows网站推出了一系列文章,详细讲解了开发者应怎样创建便于运维的Windows服务.这一系列文章详细分析了如何克服在运维部门看来最困难的部分:Windows服务 ...
- SC命令---安装、开启、配置、关闭 cmd命令行和bat批处理操作windows服务
一.cmd命令行---进行Windows服务操作 1.安装服务 sc create 服务名 binPath= "C:\Users\Administrator\Desktop\win32s ...
- C#.NET 操作Windows服务(安装、卸载)
注意点: 1.安装时要请求到管理员权限. 2.卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑.代码无法停止服务时,使用services.msc来停止. 开始: 1.新建一个名为&quo ...
- C#操作windows服务
本文主要说明了Windows服务的安装.卸载.启动.停止.获取服务安装路径.获取服务状态.检查服务是否存在.获取服务版本. 我们需要引用命名空间using System.Configuration.I ...
- C#操作windows服务,安装、卸载、停止、启动
public class ServiceUtil { private string _ServiceName = string.Empty; private string _AppName = str ...
随机推荐
- cocos2d-x3.0数据结构
1.cocos2d::Vector 1.头报价"CCVector.h"头文件. 2.保存的数据类型必须是cocos2d::Ref的子类. 3.实现是动态加入数据集合即链表.主要的使 ...
- SharePoint使用BCS开发你第一个应用程序(一)
SharePoint使用BCS开发你第一个应用程序(一) 本系列教你使用BCS(Business Connectivity Service)创建OBA(Office business ...
- C. Captain Marmot (Codeforces Round #271)
C. Captain Marmot time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- SPOJ TWOPATHS Two Paths
题目意思:给一棵树,找到俩个不相交的通路,使得这俩个通路的长度和乘机最大: 解法: 小哥一看呵呵 这不就是枚举点 然后求俩边的树的直径在相乘求个最大值的题么! 呵呵 这个N 有100000 当时就不玩 ...
- HDU-2857-Mirror and Light(计算几何)
Problem Description The light travels in a straight line and always goes in the minimal path between ...
- webclient下载文件 带进度条
private void button1_Click(object sender, EventArgs e) { doDownload(textBox1.Text.Trim()); } private ...
- 深入研究Java类载入机制
深入研究Java类载入机制 类载入是Java程序运行的第一步,研究类的载入有助于了解JVM运行过程,并指导开发人员採取更有效的措施配合程序运行. 研究类载入机制的第二个目的是让程序能动态的控制类载 ...
- 如何设置ubuntu自己主动的睡眠时间
我相信很多在学习linux的过程中.总会遇到,不时系统会冬眠自己主动,因此,即使再次输入password.么重要的内容怕别人看 另外假设你常常使用像Putty这样子的远程登录软件的话,假设你的linu ...
- IOC/DI的基本思想
IOC/DI的基本思想 1.把程序之间的依赖关系去掉 2.把程序对象设置到IOC/DI容器的配置中作为Bean 3.由IOC/D.容器来管理Bean的创建和实例化 4.由IOC/DI容器来把Bean之 ...
- MEF初体验之十一:查询组合容器
查询组合容器 组合容器暴露了几个get exports的重载方法和导出对象和对象集合.你需要注意下面的行为: 当请求单个对象实例时,如果未发现导出,一个异常将被抛出 当请求单个对象实例时,如果发现超过 ...