C#实现对Windows 服务安装
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 服务安装的更多相关文章
- Windows服务安装与卸载
Windows服务安装与卸载,使用到了InstallUtil.exe 安装: c: cd "C:\Windows\Microsoft.NET\Framework\v4.0.30319&quo ...
- Windows服务安装异常:System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志。不可 访问的日志: Security
Windows服务安装异常:System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志.不可 访问的日志: Security 2种方法处理: 一.右键 ...
- C#编写的windows服务安装后启动提示“服务启动后又停止了”
使用C#编写的windows服务安装到服务器上行后进行启动时,总是提示“服务启动后又停止了”. 检查了服务逻辑是没问题,安装在开发本地也是正常,网上查了资料说是可能是服务没有注册,我检查了服务是正常注 ...
- Windows服务安装与控制
Windows服务安装与控制 1.建立服务 (1)定义一个ServiceInstaller using System; using System.Collections.Generic; using ...
- C# windows服务安装及卸载
--C# windows服务安装及卸载 保存BAT文件 执行即可 @SET FrameworkDir=%WINDIR%\Microsoft.NET\Framework@SET Framework ...
- EasyDSS RTMP流媒体解决方案之Windows服务安装方案
Windows服务安装 EasyDSS_Solution流媒体解决方案,可以通过start一键启动.在实际应用中,我们希望可以设置成系统服务,那么下面我将会介绍,如何在windows中将流媒体解决方案 ...
- PCB MongoDb安装与Windows服务安装
工程MI流程指示做成Web网页形式,采用MVC框架制作,数据传输用Web API方式, 最终此网页会挂到公司各系统中访问,为了提高访问并发量,并将工程数据统一结构化管理, 采用No SQL Mongo ...
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Windows服务安装
背景说明 EasyDSS流媒体解决方案是由安徽旭帆信息科技有限公司自主研发的一套集流媒体点播.转码.管理.直播.录像.检索.时移回看于一体的一套完整的商用流媒体解决方案.EasyDSS软件以压缩包的形 ...
- Windows 服务安装与卸载 (通过 Sc.exe)
1. 安装 新建文本文件,重命名为 ServiceInstall.bat,将 ServiceInstall.bat 的内容替换为: sc create "Verity Platform De ...
随机推荐
- 在Eclipse中对自动封装的设定颜色
在Eclipse中,对自动封装进行特别着色提醒的方法:windows-->Preference-->java-->Editor-->Syntax Coloring-->j ...
- codewars 随手记
1.ES6数组遍历语法糖=> 在C#Linq里曾经用过,因此也不是很陌生. var range = Array.apply(null, Array(x)).map((_, i) => ++ ...
- C#通过WatiN操作页面中内嵌的Iframe
通过WatiN.Core.Broswer.Frame()方法来获取iframe对象,之后的容器就是frame,然后进行操作. 下面的例子是登录QQ空间的: Frame frame = browser. ...
- 关于超出部分隐藏加省略号的css方法
单行效果:display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; 多行效果:width: ...
- java编程经验积累
1.java批量删除checkbox中选中的对象-CSDN论坛-CSDN.NET-中国最大的IT技术社区 http://bbs.csdn.net/topics/360223125 2.重定向与转发路 ...
- 使用canvas元素-art方法绘制圆弧
最近在学习HTML5,发现canvas真的很棒,canvas元素是一种可供绘图的平面,我们用JavaScript对它进行配置和操作.我这里说一下arc方法绘制圆弧,顺便提一下涉及到的基础知识. 首先看 ...
- 【Cocos2d-x 3.x】 场景切换生命周期、背景音乐播放和场景切换原理与源码分析
大部分游戏里有很多个场景,场景之间需要切换,有时候切换的时候会进行背景音乐的播放和停止,因此对这块内容进行了总结. 场景切换生命周期 场景切换用到的函数: bool Setting::init() { ...
- windows下使用Git命令汇总
这里只是简单汇总下Git主要命令,方便记忆:汇总的不好,请各位包容,谢谢!想看详细讲解,推荐廖雪峰大神的教程,地址如下:http://www.liaoxuefeng.com/wiki/00137395 ...
- poj1852 Ants ——想法题、水题
求最短时间和最长时间. 当两个蚂蚁相遇的时候,可以看做两个蚂蚁穿过,对结果没有影响.O(N)的复杂度 c++版: #include <cstdio> #define min(a, b) ( ...
- RMAN备份与恢复之初入茅庐
理解数据库备份 所谓备份实际上是把数据库复制到转储设备的过程. 从备份方式来看数据库备份分为物理备份和逻辑备份,物理备份是把构成数据库的所有文件拷贝到指定的位置的过程,而逻辑备份只是利用SQL语言从数 ...