Windows服务作用:定时用户消息推送,WEB程序实时统计等

Windows服务创建:C#创建服务的方式也有很多种,建议大家在做之前可以先全面了解一下这方面东西再去动手这样便于解决中间遇到一些比较棘手的小问题。

主要说一种通过SC命令实现服务的创建、修改、查询、卸载、开始、暂停,具体服务工作的业务可以另行完善。

1,创建一个控制台程序,当然也可以写个winform或者其他XXX

2,在创建好的项目中新建一个服务

创建完服务,剩下的就需要代码实现了。

思路:我们将通过模拟在命令窗中输入SC服务命令创建和操作服务,所以这里先把一些公用的方法写出来。

运行命令并返回命令输出消息

 /// <summary>
/// 运行CMD命令
/// </summary>
/// <param name="cmd">命令</param>
/// <returns></returns>
public static string Cmd(string[] cmd)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.AutoFlush = true;
for (int i = ; i < cmd.Length; i++)
{
p.StandardInput.WriteLine(cmd[i].ToString());
}
p.StandardInput.WriteLine("exit");
string strRst = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
CloseProcess("cmd.exe");//执行结束,关闭cmd进程
return strRst;
}

结束Process 方法

  /// <summary>
/// 关闭进程
/// </summary>
/// <param name="ProcName">进程名称</param>
/// <returns></returns>
public static bool CloseProcess(string ProcName)
{
bool result = false;
System.Collections.ArrayList procList = new System.Collections.ArrayList();
string tempName = "";
int begpos;
int endpos;
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
tempName = thisProc.ToString();
begpos = tempName.IndexOf("(") + ;
endpos = tempName.IndexOf(")");
tempName = tempName.Substring(begpos, endpos - begpos);
procList.Add(tempName);
if (tempName == ProcName)
{
if (!thisProc.CloseMainWindow())
thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
result = true;
}
}
return result;
}

因为服务的请求可能会从系统服务或者应用程序发起请求,所以我们要加一个完善的主方法请求判断,如果是命令行过来的就给用户提供可选的操作菜单,否则运行服务。

定义一个枚举,记录不同请求来源。

  /// <summary>
/// 定义程序被启用的几种形式
/// </summary>
public enum appModel
{
/// <summary>
/// 网页启用
/// </summary>
Web,
/// <summary>
/// 系统服务启用
/// </summary>
Service,
/// <summary>
/// 窗体程序启用
/// </summary>
Windows,
/// <summary>
/// 控制台启用
/// </summary>
Console
}

主方法内添加状态判断

 static void Main(string[] args)
{
appModel mode = AutoDetectAppType();//获取应用程序请求来源
if (mode.Equals(appModel.Console))
{//如果是控制台程序,验证是否对服务操作
Console.WriteLine("选择金销帮后台服务操作");
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
var rs = int.Parse(Console.ReadLine());
DoParameter(rs);
}
else if (mode.Equals(appModel.Service))
{
//如果是服务,运行系统服务
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MainServer(),
};
ServiceBase.Run(ServicesToRun);
}
}

根据用户每次选择不同的菜单对Windows服务发出命令

 /// <summary>
/// 判断用户输入参数
/// </summary>
/// <param name="rs">控制台输入参数</param>
public static void DoParameter(int rs)
{
//[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出
switch (rs)
{
case :
//查询
string back_query = Cmd(new string[] { "sc query jinxiaobangServices" });//查询服务信息
Console.WriteLine("------------------------------------------------------------------------------------");
Console.WriteLine("查询服务信息如下:\n\n\n " + back_query);//输出查询结果
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
Console.WriteLine("------------------------------------------------------------------------------------"); var param_query = int.Parse(Console.ReadLine());
DoParameter(param_query);
break;
case :
//安装服务
var path = Process.GetCurrentProcess().MainModule.FileName;
string back_create = Cmd(new string[] { "sc create jinxiaobangServices binpath= \"" + path + "\" displayName= JXBServices start= auto obj= localsystem ", "sc description \"jinxiaobangServices\" \"金销帮后台异步通知、数据统计、定时任务等处理\" " });
Console.WriteLine("------------------------------------------------------------------------------------");
Console.WriteLine("安装成功\n\n\n" + back_create);
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
Console.WriteLine("------------------------------------------------------------------------------------"); var param_create = int.Parse(Console.ReadLine());
DoParameter(param_create);
break;
case :
//卸载服务
string back_delete = Cmd(new string[] { "sc delete jinxiaobangServices" });//卸载服务
Console.WriteLine("------------------------------------------------------------------------------------");
Console.WriteLine("卸载成功\n\n\n" + back_delete);
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
Console.WriteLine("------------------------------------------------------------------------------------"); var param_delete = int.Parse(Console.ReadLine());
DoParameter(param_delete);
break;
case :
//启动服务
//Process.Start("sc", "start jinxiaobangServices");//sc执行命令
string back_start = Cmd(new string[] { "sc start jinxiaobangServices" });//启动服务
Console.WriteLine("------------------------------------------------------------------------------------");
Console.WriteLine("启动成功\n\n\n" + back_start);
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
Console.WriteLine("------------------------------------------------------------------------------------"); var param_start = int.Parse(Console.ReadLine());
DoParameter(param_start);
break;
case :
//停止服务
string back_stop = Cmd(new string[] { "sc stop jinxiaobangServices" });//停止服务
Console.WriteLine("------------------------------------------------------------------------------------");
Console.WriteLine("停止服务\n\n\n" + back_stop);
Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
Console.WriteLine("------------------------------------------------------------------------------------"); var param_stop = int.Parse(Console.ReadLine());
DoParameter(param_stop);
//退出
break;
case :
//退出
break;
}
}

到这里就把整个服务操作过程了解清楚了,后面就可以准备自己的业务代码。例如服务启动时和停止时分别做一些业务操作

 protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
FileStream fs = new FileStream(@"C:\Windows\JinXBWinServer.log", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.BaseStream.Seek(, SeekOrigin.End);
sw.WriteLine("WindowsService: Service Started" + DateTime.Now.ToString() + "\n");
sw.Flush();
sw.Close();
fs.Close();
} protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
FileStream fs = new FileStream(@"C:\Windows\JinXBWinServer.log", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.BaseStream.Seek(, SeekOrigin.End);
sw.WriteLine("WindowsService: Service Stopped" + DateTime.Now.ToString() + "\n");
sw.Flush();
sw.Close();
fs.Close();
}

可以分别通过OnStart和OnStop去记录一下服务操作记录,来做个测试。

服务编写完,先别急着F5测试。因为运行权限的问题,这时可能会出现1053:服务没有及时响应启动或控制请求。这是因为VS权限不足,可以在debug文件中用管理员运行测试一下,是不是OK了。

特别注意:每次更新安装都要用最新的SetUp.exe安装包,点击右键生成可以自动在“SetUp\Express\SingleImage\DiskImages\DISK1\setup.exe”路径下生成exe安装文件,一定记得安装最新版。

InstallShield Limited Edition for Visual Studio的具体使用,可以网上找一下,也可以参考这里:http://blog.csdn.net/kingmax54212008/article/details/44303539

C#实现对Windows 服务安装的更多相关文章

  1. Windows服务安装与卸载

    Windows服务安装与卸载,使用到了InstallUtil.exe 安装: c: cd "C:\Windows\Microsoft.NET\Framework\v4.0.30319&quo ...

  2. Windows服务安装异常:System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志。不可 访问的日志: Security

    Windows服务安装异常:System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志.不可 访问的日志: Security 2种方法处理: 一.右键 ...

  3. C#编写的windows服务安装后启动提示“服务启动后又停止了”

    使用C#编写的windows服务安装到服务器上行后进行启动时,总是提示“服务启动后又停止了”. 检查了服务逻辑是没问题,安装在开发本地也是正常,网上查了资料说是可能是服务没有注册,我检查了服务是正常注 ...

  4. Windows服务安装与控制

    Windows服务安装与控制 1.建立服务 (1)定义一个ServiceInstaller using System; using System.Collections.Generic; using ...

  5. C# windows服务安装及卸载

    --C# windows服务安装及卸载   保存BAT文件  执行即可 @SET FrameworkDir=%WINDIR%\Microsoft.NET\Framework@SET Framework ...

  6. EasyDSS RTMP流媒体解决方案之Windows服务安装方案

    Windows服务安装 EasyDSS_Solution流媒体解决方案,可以通过start一键启动.在实际应用中,我们希望可以设置成系统服务,那么下面我将会介绍,如何在windows中将流媒体解决方案 ...

  7. PCB MongoDb安装与Windows服务安装

    工程MI流程指示做成Web网页形式,采用MVC框架制作,数据传输用Web API方式, 最终此网页会挂到公司各系统中访问,为了提高访问并发量,并将工程数据统一结构化管理, 采用No SQL Mongo ...

  8. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Windows服务安装

    背景说明 EasyDSS流媒体解决方案是由安徽旭帆信息科技有限公司自主研发的一套集流媒体点播.转码.管理.直播.录像.检索.时移回看于一体的一套完整的商用流媒体解决方案.EasyDSS软件以压缩包的形 ...

  9. Windows 服务安装与卸载 (通过 Sc.exe)

    1. 安装 新建文本文件,重命名为 ServiceInstall.bat,将 ServiceInstall.bat 的内容替换为: sc create "Verity Platform De ...

随机推荐

  1. HDU 5384 AC自动机

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:给n个母串,给m个匹配串,求每个母串依次和匹配串匹配,能得到的数目和. 分析:之前并不知道AC ...

  2. C#常用操作类库四(File操作类)

    public class FileHelper : IDisposable { private bool _alreadyDispose = false; #region 构造函数 public Fi ...

  3. iOS--时间类date详解

    NSDate定义时间的类 NSDate是一个时间类,在编写程序时,我们很少遇到.今天我突然碰到,感觉很生疏. 给大家发个博客,让大家也都温习一下,哈哈! 兄弟用的时候突然发现竟然有一些bug,大家用时 ...

  4. js 判断浏览器的类型

    function getBrowser() {    var Sys = {};    var ua = navigator.userAgent.toLowerCase();    var s;    ...

  5. webclient的简单实用

    这是我在项目中调用别人写好的接口口是使用的1.简单的url传参 List<ArticleModel> result = new List<ArticleModel>(); st ...

  6. LPTHW 笨办法学python 37章 python关键字/关键词介绍

    本章简要的介绍了各种关键词: and:[布尔运算]且 del: 删除变量(函数,类) from: 从某一个库或者文件读取 not:[布尔运算]非 while: while-loop 关键字,后跟循环条 ...

  7. js数字时钟

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. HDU 1285 确定比赛排名 (数组实现 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    ...

  9. HDFS的工作原理(读和写操作)

    工作原理: NameNode和DateNode,NameNode相当于一个管理者,它管理集群内的DataNode,当客户发送请求过来后,NameNode会 根据情况指定存储到哪些DataNode上,而 ...

  10. java考核完的心得

    2015年8月13日     星期四      晴 今天上午我们考核了java,就是用Java语言写一个小型的管理系统.考核前的我信心满满,因为我本身是测试专业的,觉得在开发这方面对自己不用要求的那么 ...