参考:https://www.cnblogs.com/cncc/p/7170951.html

一、开发环境

  操作系统:Windows 7 X64

  开发环境:VS2017

  编程语言:C#

  .NET版本:.NET Framework 4.6.1

  目标平台:Any CUP

二、创建Windows Service

1、新建一个Windows Service,并将项目名称改为“WindowsService1”,如下图所示:

2、进入“Service1”设计界面,在空白位置右击鼠标弹出上下文菜单,选中“添加安装程序”,如下图所示:

3、此时软件会生成两个组件,分别为“serviceInstaller1”及“serviceProcessInstaller1”,如下图所示:

4、设置“serviceInstaller1”及“serviceProcessInstaller1”的属性

5、至此,Windows服务已经创建完毕。

三、创建安装、启动、停止、卸载服务的Windows窗体

1、在同一个解决方案里新建一个Windows Form项目,并命名为WindowsFormsApp1,如下图所示:

2、将该项目设置为启动项目,并在窗体内添加四个按钮,分别为安装服务、启动服务、停止服务及卸载服务,如下图所示:

3、按下F7进入代码编辑界面,引用“System.ServiceProcess”及“System.Configuration.Install”,并输入如下代码:

using System;
using System.Collections;
using System.Configuration.Install;
using System.ServiceProcess;
using System.Windows.Forms; namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string serviceFilePath = $"{Application.StartupPath}\\WindowsService1.exe";
string serviceName = "Service1"; /// <summary>
/// 安装服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
if (this.IsServiceExisted(serviceName))
{
this.UninstallService(serviceFilePath);
}
this.InstallService(serviceFilePath);
} /// <summary>
/// 启动服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
if (this.IsServiceExisted(serviceName))
{
this.ServiceStart(serviceName);
}
}
/// <summary>
/// 停止服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
if (this.IsServiceExisted(serviceName))
{
this.ServiceStop(serviceName);
}
}
/// <summary>
/// 卸载服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
if (this.IsServiceExisted(serviceName))
{
this.ServiceStop(serviceName);
this.UninstallService(serviceFilePath);
}
} #region 方法
/// <summary>
/// 判断服务是否存在
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
private bool IsServiceExisted(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController sc in services)
{
if (sc.ServiceName.ToLower() == serviceName.ToLower())
{
return true;
}
}
return false;
} /// <summary>
/// 安装服务
/// </summary>
/// <param name="serviceFilePath"></param>
private void InstallService(string serviceFilePath)
{
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
IDictionary savedState = new Hashtable();
installer.Install(savedState);
installer.Commit(savedState);
}
} /// <summary>
/// 卸载服务
/// </summary>
/// <param name="serviceFilePath"></param>
private void UninstallService(string serviceFilePath)
{
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
installer.Uninstall(null);
}
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="serviceName"></param>
private void ServiceStart(string serviceName)
{
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Stopped)
{
control.Start();
}
}
} /// <summary>
/// 停止服务
/// </summary>
/// <param name="serviceName"></param>
private void ServiceStop(string serviceName)
{
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Running)
{
control.Stop();
}
}
}
#endregion
}
}

4、为了后续调试服务及安装卸载服务的需要,将已生成的MyWindowsService.exe引用到本Windows窗体,如下图所示:

5、由于需要安装服务,故需要使用UAC中Administrator的权限,鼠标右击项目“WindowsServiceClient”,在弹出的上下文菜单中选择“添加”->“新建项”,在弹出的选择窗体中选择“应用程序清单文件”并单击确定,如下图所示:

6、打开该文件,并将<requestedExecutionLevel level="asInvoker" uiAccess="false" />改为<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />,如下图所示:

Windows Service 学习系列(一):建立简单的Windows service的更多相关文章

  1. Windows程序设计学习笔记(1):一个简单的windows程序

    <Windows程序设计>(第五版)(美Charles Petzold著) #include<windows.h> LRESULT CALLBACK WndProc(HWND, ...

  2. Docker学习系列(一):windows下安装docker(转载)

    本文目录如下: windows按照docker的基本要求 具体安装步骤 开始使用 安装远程连接工具连接docker 安装中遇到的问题 Docker的更新 Docker中的jupyter windows ...

  3. 《windows核心编程系列》十八谈谈windows钩子

    windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...

  4. Windows Service 学习系列(二):C# windows服务:安装、卸载、启动和停止Windows Service几种方式

    一.通过InstallUtil.exe安装.卸载.启动.停止Windows Service 方法一 1.以管理员身份运行cmd 2.安装windows服务 切换cd C:\Windows\Micros ...

  5. Windows Service 学习系列(三)——循环引擎 ICycleEngine

    摘要:转载:https://www.cnblogs.com/zhuweisky/archive/2009/09/01/1557792.html#undefined 1.缘起: 有些系统需要每隔一段时间 ...

  6. 【Ngui 学习系列之一:简单组件的操作】

    一.Buttonunity edit: Sprite作为父对象和背景 -- Collider -- Button script Label 作为子对象和显示文字代码: private UIButton ...

  7. 《windows核心编程系列》十五谈谈windows线程栈

    谈谈windows线程栈. 当系统创建线程时会为线程预订一块地址空间区域,注意仅仅是预订.默认情况下预定的这块区域的大小是1MB,虽然预订这么多,但是系统并不会给全部区域调拨物理存储器.默认情况下,仅 ...

  8. 《Windows核心编程系列》十二谈谈Windows内存体系结构

    Windows内存体系结构 理解Windows内存体系结构是每一个励志成为优秀的Windows程序员所必须的. 进程虚拟地址空间 每个进程都有自己的虚拟地址空间.对于32位操作系统来说,它的地址空间是 ...

  9. Silverlight for Windows Phone开发系列课程

    Silverlight for Windows Phone开发系列课程(1):Windows Phone平台概况         课程简介:本节开始介绍系列课程的概况,包括课程内容,先决条件,学习目的 ...

随机推荐

  1. AbstractQueuedSynchronizer源码分析(ReentrantLock锁的实现)

    1.  前言 Java中好多地方用到AbstractQueuedSynchronizer(PS:简称AQS),比如ReentrantLock.线程池,这部分在面试的时候也经常被问到,今天以Reentr ...

  2. MyEclipse 新手使用教程---图文详解

    引言 某天在群里看到有小伙伴问MyEclipse/Eclipse的一些使用问题,虽然在我看来,问的问题很简单,但是如果对于刚刚学习的人来说,可能使用就不那么友好了.毕竟我在开始使用MyEclipse/ ...

  3. Linux基础知识第三讲,拷贝文件跟移动文件命令

    目录 Linux基础知识第三讲,拷贝文件跟移动文件命令 一丶常用命令 1.tree命令常用选项 2.cp复制文件命令 3.mv 命令的使用 Linux基础知识第三讲,拷贝文件跟移动文件命令 一丶常用命 ...

  4. Docker最全教程——从理论到实战(四)

    往期内容链接 https://www.cnblogs.com/codelove/p/10030439.html https://www.cnblogs.com/codelove/p/10036608. ...

  5. js for循环删除两个数组相同元素

    var id = ['a','b','c','a','d','a','a','b','d','c','a','b','c','a','b','c'] var del = ['a','c']; var ...

  6. 委托初级篇——lambda表达式的推导

    public delegate void ConsoleWriteStr(string name,DateTime now); public delegate int DelegateAdd(int ...

  7. 杭电ACM2015--偶数求和

    偶数求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. [PHP] strpos stripos strrpos strripos的区别

    stripos — 查找字符串首次出现的位置(不区分大小写),应使用 === 运算符来测试此函数的返回值 strpos 左边开始字符出现的第一个位置,区分大小写stripos 和上面一样,不区分大小写 ...

  9. centos-linux入门笔记

    一.linux的用户 linux的用户和windwos差不多,分为管理员用户和普通用户. 普通用户:权限没那么高而已. 管理员用户:在linux中就是root用户,所拥有的权限是最高的. 二.linu ...

  10. IIS中虚拟目录不继承主站点web.config设置的办法(转载)

    ASP.NET提供了强大的Web.config来配置网站,一般来说一个网站只有一个根目录下的Web.config文件,有时候我们希望子目录有着不同的权限或者参数设置,则可以在相应子目录增加一个Web. ...