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. 如何启动app时全屏显示Default.png(图片)?

  2. 关于调用deleteRowsAtIndexPaths withRowAnimation方法出现错误

    通常原因是因为 这个方法的调用与数据源有关. 检测1.你的数据源是否写死了. 2.调用该方法前你是否移除相关的数据源 相关的核心代码如下: - (NSInteger)tableView:(UITabl ...

  3. css3-实现3D立方体旋转

    核心内容: 1.CSS3 中 animation.perspective 属性的熟练运用. 2.CSS3 中的变形属性 transform,在 3D 立体效果中的运用. 3.3D 立方体旋转实现原理. ...

  4. 服务器三大体系SMP、NUMA、MPP介绍

    从系统架构来看,目前的商用服务器大体可以分为三类,即: 对称多处理器结构(SMP:Symmetric Multi-Processor) 非一致存储访问结构(NUMA:Non-Uniform Memor ...

  5. iOS 源代码管理工具之SVN

    源代码管理工具之SVN 源代码管理工具SVN是一款非常强大的源代码管理工具,现在国内70%-90%的公司都在使用SVN来管理源代码,下面就让小编给大家着重介绍一下SVN的使用,SVN的使用主要分为下面 ...

  6. Android 中onConfigurationChanged问题

    onConfigurationChanged 不生效问题解决方案: 1).首先,需要重写onConfigurationChanged函数 @Override    public void onConf ...

  7. esrdtfyghjk

    两融余额止跌回升,金融股回落飘绿,千股涨停续演,沪指收复4000点未果涨逾2% 相关报道 [今日收盘]灾后重建激情抢筹 大盘两日反弹500点 [今日收盘]沪指涨近6%重回3700点 未停牌个股九成涨停 ...

  8. 网络虚拟化中的 offload 技术:LSO/LRO、GSO/GRO、TSO/UFO、VXLAN

    offload 现在,越来越多的网卡设备支持 offload 特性,来提升网络收/发性能.offload 是将本来该操作系统进行的一些数据包处理(如分片.重组等)放到网卡硬件中去做,降低系统 CPU ...

  9. bash 取文件特定行

    比如,想要取某文件10-20行 可以用sed sed -n '10,20p' XXX.txt 非常方便!

  10. UE4 Windows平台部署游戏到IOS 第二部分

    点击加号后会出来如下截图 勾选上红色单选框处(因为这个我已经申请过了所以是灰色),然后continue到后面会出现下图 选择一个之前我提到申请证书会用的的那个.csr后缀文件夹,完成以后就可以下载证书 ...