c#创建Windows服务,并用批处理安装与卸载

        最近写了个控制台应用程序,功能是监控对应文件夹内DICOM文件,若有文件则读取进行处理,处理后将文件移除。其中没有任何手动输入,程序又需要一直运行,但是控制台应用容易被随手关掉,所以决定做成服务。话不多说,从创建开始记录~

一、创建编写Windows服务

1.创建项目

选择创建Windows服务,更改项目名称和位置,如下图

c#创建Windows服务,并用批处理安装与卸载_第1张图片

2.添加安装程序(添加后才能将你的Windows服务安装,不然无法启动)

成功创建后,出现如下界面

c#创建Windows服务,并用批处理安装与卸载_第2张图片
或双击生成的,出现上图设计界面

在空白处右击,出现菜单单击添加安装程序

c#创建Windows服务,并用批处理安装与卸载_第3张图片

出现如下画面

c#创建Windows服务,并用批处理安装与卸载_第4张图片

分别右击两个组件更改其属性

c#创建Windows服务,并用批处理安装与卸载_第5张图片

c#创建Windows服务,并用批处理安装与卸载_第6张图片

3.编写服务代码

c#创建Windows服务,并用批处理安装与卸载_第7张图片

构造函数里面写初始化代码,OnStart里面是服务器开启时运行的函数,OnStop里面是服务器停止时运行的函数,

注意:不要在这两个函数里面写死循环,不然服务无法运行,因为运行完函数才会服务才会开启,不然就会处于"启动"的状态,既不是已启动也不是没启动,无法停止也无法启动,只能直接卸载掉。

我写了个测试方法,将信息写入名为当前日期的txt文件中,代码如下:

public Service1()
{
    InitializeComponent();
    creatf("Initialization");

}

protected override void OnStart(string[] args)
{
    creatf("OnStart");
}

protected override void OnStop()
{
    creatf("OnStop");
}
public void creatf(string str)//操作日志
        {
            //获取当前日期
            string s = DateTime.Now.ToString("yyyy-MM-dd");
            string time = DateTime.Now.ToLongTimeString().ToString();
            string path = Directory.GetCurrentDirectory()+"\\log";

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            path = path +"\\"+ s + ".txt";
            if (!File.Exists(path))
            {
                FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs);
                long fl = fs.Length;
                fs.Seek(fl, SeekOrigin.End);
                sw.WriteLine("[" + DateTime.Now.ToString("F") + "]:" + str + "\n");//开始写入值
                sw.Close();
                fs.Close();


            }
            else
            {
                FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs);
                long fl = fs.Length;
                fs.Seek(fl, SeekOrigin.Begin);
                sw.WriteLine("[" + DateTime.Now.ToString("F") + "]:" + str + "\n");//开始写入值
                sw.Close();
                fs.Close();
            }
        }

其中Directory.GetCurrentDirectory()是获取项目的当前目录,但是注册成服务后,这个目录就变成了C:\Windows\System32(或C:\Windows\SysWOW64),这样没有达到想要的效果。

所有的Windows服务都在注册表中有对应记录,其中imagepath就是你的服务.exe安装的目录,对此可以添加一个获取服务安装路径的函数:

/// 
/// 获取服务安装路径
/// 
/// 
/// 
public static string GetWindowsServiceInstallPath(string ServiceName)
{
    string key = @"SYSTEM\CurrentControlSet\Services\" + ServiceName;
    string path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();
    //替换掉双引号
    path = path.Replace("\"", string.Empty);
    FileInfo fi = new FileInfo(path);
    return fi.Directory.ToString();
}

由此可将creatf函数中的Directory.GetCurrentDirectory()改为GetWindowsServiceInstallPath("你的服务名称")

生成项目无错ok

二、安装与卸载服务

生成的exe是不能直接打开的,需要安装,安装有多种方法,这里介绍通过批处理文件安装。

1.安装

新建txt文件,更改后缀为.bat,用记事本打开编辑如下。

@echo.请稍等,服务启动......
@echo off
@sc create testName binPath= "%~dp0%WindowsService2.exe"
@net start testName 
@sc config testName  start= AUTO
@sc description testName 这是一个测试服务
@echo off
@echo.启动完毕!
@pause

testName是服务的名称,

binPath是生成的exe文件,%~dp0%是批处理文件所在目录,也可改成绝对路径

description是显示的服务描述

成功效果如下:

c#创建Windows服务,并用批处理安装与卸载_第8张图片

此时服务已经启动,运行了之前写的代码,在生成log目录和名为当前日期的文件

c#创建Windows服务,并用批处理安装与卸载_第9张图片

c#创建Windows服务,并用批处理安装与卸载_第10张图片

2.卸载

新建txt文件,更改后缀为.bat,用记事本打开编辑如下。

@echo.服务卸载......  
@echo off  
@sc stop testName
@sc delete testName
@sc stop testName
@echo off  
@echo.卸载完毕!  
@pause 
 

成功效果如下:

c#创建Windows服务,并用批处理安装与卸载_第11张图片

 

 

至此整个流程都完成了,有疑问或错误请指出,谢谢

新更新一直安装服务的bat,一句ok

安装:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe AutoInspectionSys.exe

卸载:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u AutoInspectionSys.exe

你可能感兴趣的:(c#)