关于C#创建windows服务的测试与总结

.NET中安装服务很麻烦,即要创建Service,又要创建ServiceInstall,最后还要弄一堆命令来安装和卸载。

今天给大家提供一种方式(经过测试),直接使用这样的程序来安装/卸载服务,并且可以让一个exe即能直接运行也可以安装为windows服务(运行exe文件时需要以管理员身份运行,卸载服务也需要管理员身份,否则可能会报错,并且在程序中直接运行服务时可能会报错,建议运行exe文件)

修改管理员身份:

用SC命令 添加或删除windows服务提示OpenSCManager 失败5 拒绝访问在安装命令行中安装  windowsOpenSCManager 失败5  的错误,原因是当前用户的权限不足,需要做的是在注册表:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA 的值改为0把这个值改成0,这样在自己的电脑上操作才是真正的administration,然后重启。

创建C#服务的普通方法: http://blog.sina.com.cn/s/blog_6d5459990102uymo.html ,下面是改进过程。

首先我们创建一个Windows应用程序,(我创建的是控制台程序,WinForm也一样)

 

 

接下来在项目中添加一个Windows服务类

 

然后双击“MainService.cs”,在上面点右键“打开代码”

 

这里面写服务的具体实现,以下是我写的示例代码

复制代码
复制代码
 partial class MainService : ServiceBase
    {
        public MainService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            // TODO:  在此处添加代码以启动服务。
            System.IO.File.AppendAllText("D:\\log.txt", "服务已启动……" + DateTime.Now.ToString());
        }

        protected override void OnStop()
        {
            // TODO:  在此处添加代码以执行停止服务所需的关闭操作。
            System.IO.File.AppendAllText("D:\\log.txt", "服务已停止……" + DateTime.Now.ToString());
        }
    }
复制代码
复制代码

然后我们改程序入口Main方法,让其在启动时识别是Windows应用程序还是Windows服务,如果是应用程序就执行应用程序的代码,如果是服务就执行MainService的代码

如果是服务,我给了一个"s"参数,如果有这个参数就证明是Windows服务,然后启动MainService

复制代码
复制代码
 static void Main(string[] args)
        {
           //如果传递了"s"参数就启动服务
            if (args.Length > 0 && args[0] == "s")
            {
               //启动服务的代码,可以从其它地方拷贝
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] 
                { 
                    new MainService(),
                };
                ServiceBase.Run(ServicesToRun);
            }
            else
            {}
复制代码
复制代码

然后,我们再实现应用程序的功能,就是上面的else语句块,应用程序的功能就是安装/卸载服务,可以用windows自带的sc命令来进行安装和卸载,具体代码如下:

复制代码
复制代码
                Console.WriteLine("这是Windows应用程序");
                Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");
                var rs = int.Parse(Console.ReadLine());
                switch (rs)
                {
                    case 1:
                        //取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序
                        var path = Process.GetCurrentProcess().MainModule.FileName + " s";
                        Process.Start("sc", "create myserver binpath= \"" + path + "\" displayName= 我的服务 start= auto");
                        Console.WriteLine("安装成功");
                        Console.Read();
                        break;
                    case 2:
                        Process.Start("sc", "delete myserver");
                        Console.WriteLine("卸载成功");
                        Console.Read();
                        break;
                    case 3: break;
                }
复制代码
复制代码

这样我们就实现了一个即是可执行程序又是Windows服务的应用程序

Main方法完整代码如下

复制代码
复制代码
 static void Main(string[] args)
        {
            if (args.Length > 0 && args[0] == "s")
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] 
                { 
                    new MainService(),
                };
                ServiceBase.Run(ServicesToRun);
            }
            else
            {
                Console.WriteLine("这是Windows应用程序");
                Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");
                var rs = int.Parse(Console.ReadLine());
                switch (rs)
                {
                    case 1:
                        //取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序
                        var path = Process.GetCurrentProcess().MainModule.FileName + " s";
                        Process.Start("sc", "create myserver binpath= \"" + path + "\" displayName= 我的服务 start= auto");
                        Console.WriteLine("安装成功");
                        Console.Read();
                        break;
                    case 2:
                        Process.Start("sc", "delete myserver");
                        Console.WriteLine("卸载成功");
                        Console.Read();
                        break;
                    case 3: break;
                }
            }
        }
复制代码
复制代码

至此,程序已基本写完,接下来我们测试一下

直接双击ServiceOrApp.exe

 

输入 1

提示安装成功,然后运行“services.msc"打开服务管理器

可以发现我们的服务已安装成功,然后右键启动服务

 

成功启动

然后去D盘看看log.txt

 

说明服务执行正常

我们再停止服务

 

成功停止后再看看D盘的log.txt文件

 看到以上内容,说明服务启动和停止都没问题(C#回车换行使用“\r\n”)

然后我们再试一下卸载服务(需要停止服务运行),还是双击ServiceOrApp.exe,选择2

 

提示卸载成功,然后再运行“services.msc"打开服务管理器

 刷新后以看到已经没有”我的服务“了,已成功卸载

这里安装和卸载主要运用了windows的sc命令,然后使用启动参数来判断是服务还是程序以执行不同的代码


C#windows service服务安装、注册、判断服务是否存在、是否启动 

#region 安装服务  

private void InstallService(IDictionary stateSaver, string filepath)  
{  
    try  
    {  
        ServiceController service = new ServiceController("ServiceName");  
        if (!ServiceIsExisted("ServiceName"))  
        {  
            //Install Service  
            AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();  
            myAssemblyInstaller.UseNewContext = true;  
            myAssemblyInstaller.Path = filepath;  
            myAssemblyInstaller.Install(stateSaver);  
            myAssemblyInstaller.Commit(stateSaver);  
            myAssemblyInstaller.Dispose();  
            //--Start Service  
            service.Start();  
        }  
        else  
        {  
            if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)  
            {  
                service.Start();  
            }  
        }  
    }  
    catch (Exception ex)  
    {  
        MessageBox.Show("安装服务失败!");  
    }  
}  
#endregion  
 
#region 卸载windows服务  
private void UnInstallService(string filepath)  
{  
    try  
    {    if (ServiceIsExisted("ServiceName"))  
        {  
            //UnInstall Service  
            AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();  
            myAssemblyInstaller.UseNewContext = true;  
            myAssemblyInstaller.Path = filepath;  
            myAssemblyInstaller.Uninstall(null);  
            myAssemblyInstaller.Dispose();  
        }  
    }  
    catch (Exception ex)  
    {  
        MessageBox.Show("卸载服务失败!");  
    }  
}  
#endregion  
 
#region 判断window服务是否存在 
private bool ServiceIsExisted(string serviceName)  
{  
    ServiceController[] services = ServiceController.GetServices();  
    foreach (ServiceController s in services)  
    {  
        if (s.ServiceName == serviceName)  
        {  
            return true;  
        }  
    }  
    return false;  
}  
#endregion  
 
#region 判断window服务是否启动  
public static bool IsServiceStart(string serviceName)  
{  
    ServiceController psc = new ServiceController(serviceName);  
    bool bStartStatus = false;  
    try  
    {  
        if (!psc.Status.Equals(ServiceControllerStatus.Stopped))  
        {  
            bStartStatus = true;  
        }  
  
        return bStartStatus;  
    }  
    catch (Exception ex)  
    {  
        throw new Exception(ex.Message);  
    }  
}  
#endregion  
 
#region 启动服务 
private bool StartService(string serviceName)  
{  
    bool flag = true;  
    if (ServiceIsExisted(serviceName))  
    {  
        System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);  
        if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)  
        {  
            service.Start();  
            for (int i = 0; i < 60; i++)  
            {  
                service.Refresh();  
                System.Threading.Thread.Sleep(1000);  
                if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)  
                {  
                    break;  
                }  
                if (i == 59)  
                {  
                    flag = false;  
                }  
            }  
        }  
    }  
    return flag;  
}  
#endregion  
 
#region 停止服务  
private bool StopService(string serviceName)  
{  
    bool flag = true;  
    if (ServiceIsExisted(serviceName))  
    {  
        System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);  
        if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)  
        {  
            service.Stop();  
            for (int i = 0; i < 60; i++)  
            {  www.2cto.com
                service.Refresh();  
                System.Threading.Thread.Sleep(1000);  
                if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)  
                {  
                    break;  
                }  
                if (i == 59)  
                {  
                    flag = false;  
                }  
            }  
        }  
    }  
    return flag;  
}  
#endregion  
#endregion  


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值