使用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服务的更多相关文章

  1. C# 操作windows服务[启动、停止、卸载、安装]

    主要宗旨:不已命令形式操作windows服务 static void Main(string[] args) { var path = @"E:\开发辅助项目\WCF\WCF.Test\WC ...

  2. C#通过SC命令和静态公共类来操作Windows服务

    调用的Windows服务应用程序网址:http://www.cnblogs.com/pingming/p/5115304.html 一.引用 二.公共静态类:可以单独放到类库里 using Syste ...

  3. cmd命令行和bat批处理操作windows服务(转载)

    一.cmd命令行---进行Windows服务操作 1.安装服务 sc create 服务名 binPath= "C:\Users\Administrator\Desktop\win32srv ...

  4. C#.NET 操作Windows服务承载WCF

    Windows服务的制作.安装可以参考这篇: C#.NET 操作Windows服务(安装.卸载) - runliuv - 博客园 (cnblogs.com) 本篇会在这个解决方案基础上,继续修改. 一 ...

  5. 开发便于运维的Windows服务

    过去几个月,DevOps on Windows网站推出了一系列文章,详细讲解了开发者应怎样创建便于运维的Windows服务.这一系列文章详细分析了如何克服在运维部门看来最困难的部分:Windows服务 ...

  6. SC命令---安装、开启、配置、关闭 cmd命令行和bat批处理操作windows服务

      一.cmd命令行---进行Windows服务操作 1.安装服务 sc create 服务名 binPath= "C:\Users\Administrator\Desktop\win32s ...

  7. C#.NET 操作Windows服务(安装、卸载)

    注意点: 1.安装时要请求到管理员权限. 2.卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑.代码无法停止服务时,使用services.msc来停止. 开始: 1.新建一个名为&quo ...

  8. C#操作windows服务

    本文主要说明了Windows服务的安装.卸载.启动.停止.获取服务安装路径.获取服务状态.检查服务是否存在.获取服务版本. 我们需要引用命名空间using System.Configuration.I ...

  9. C#操作windows服务,安装、卸载、停止、启动

    public class ServiceUtil { private string _ServiceName = string.Empty; private string _AppName = str ...

随机推荐

  1. VMware vSphere 服务器虚拟化之十七 桌面虚拟化之安装View链接服务器

    VMware vSphere 服务器虚拟化之十七 桌面虚拟化之安装View链接服务器 View链接服务器(View Connection Server)是Vmware Horizon View桌面虚拟 ...

  2. 2048 Puzzle游戏攻略

    2048 Puzzle这是目前手机游戏的很火. 在地铁上经常看到的人玩这个游戏. 首先,简介2048 Puzzle游戏. 游戏界面是4X4广场格,每一方格可以放置在数字. 有四种移动数字的方法,向左. ...

  3. 达到J2EE在后台action控制接待javascript弹出的对话框

    1.后台Action于: request.setAttribute("message", "这项username要么password错误,请重新输入!"); 2 ...

  4. CAS实现SSO单点登录原理(转)

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

  5. window.history.back()的改进方法window.history.go()

    今天在做项目时,測试人员提出了一条bug,起初没当回事,在改动过程中才意识到其重要性,故记录下来. 依照需求,系统应该实现例如以下的功能:有三个关联的页面a.aspx(简称a),b.aspx(简称b) ...

  6. hdu 4661 Message Passing(木DP&amp;组合数学)

    Message Passing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  7. Gas Station [leetcode] 两个解决方案

    因为gas的总数大于cost总时间.你将能够圈住整个城市. 第一溶液: 如果一開始有足够的油.从位置i出发.到位置k时剩余的油量为L(i,k). 对随意的k.L(i,k)依据i的不同,仅仅相差常数. ...

  8. java提高篇(五)-----使用序列化实现对象的拷贝

          我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性 ...

  9. .NET 4 并行(多核)编程系列之四 Task的休眠

    原文:.NET 4 并行(多核)编程系列之四 Task的休眠 .NET 4 并行(多核)编程系列之四 Task的休眠 前言:之前的几篇文章断断续续的介绍了Task的一些功能:创建,取消.本篇介绍Tas ...

  10. 一切从编辑器说起:web前端代码编辑器

    俗话说:工欲善其事,必先利其器. 工欲善其事必先利其器.谓工匠想要使他的工作做好,一定要先让工具锋利.比喻要做好一件事,准备工作非常重要. 前端写代码也是一样,需要一个好的适合自己的代码编辑器. 我想 ...