一、创建Windows服务

使用VS创建一个新的windows服务应用程序

创建完成之后

二、相关配置

修改Service1名称为StartService(可以不改,自行选择

添加安装程序并修改配置

安装完成之后,源码中会出现一个ProjectInstaller程序集,双击进入页面修改相关属性

              

   

添加文件夹和实体类

LogHelper.cs

 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace WindowsService.Common
{
public class LogHelper
{
/// <summary>
/// 获取程序异常信息
/// </summary>
/// <param name="methodBase"></param>
/// <param name="exception"></param>
/// <param name="message"></param>
/// <returns></returns>
public static string GetExceptionMessage(MethodBase methodBase, Exception exception, string message)
{
string fullName = methodBase.ReflectedType.FullName;
string name = methodBase.Name;
string str = $"\r\n异常综合信息(类:{fullName};函数名称:{name};):\r\n";
str += "-----------\r\n";
str += ".Net异常信息:\r\n";
if (exception == null)
{
str += " 无异常对象,也无堆栈信息(exception == null)\r\n";
}
else
{
str += $" {exception.Message}\r\n";
str += $".Net堆栈信息:\r\n{exception.StackTrace}\r\n";
}
str += "-----------\r\n";
if (message != null && message.Trim().Length > )
{
str += "===========\r\n";
str += $"自定义信息:\r\n {message}\r\n";
str += "===========\r\n";
}
return str;
} /// <summary>
/// 写出日志信息 目录地址:string logPath = AppDomain.CurrentDomain.BaseDirectory + "00_Log\\";
/// </summary>
/// <param name="folderName"></param>
/// <param name="message"></param>
public static void Write(string folderName, string message)
{
string text = AppDomain.CurrentDomain.BaseDirectory + "00_Log\\";
if (folderName != null && folderName.Trim().Length > )
{
text += folderName;
}
WritingLogs(text, message);
} /// <summary>
/// 写出异常日志(.txt)
/// </summary>
/// <param name="strPath"></param>
/// <param name="strContent"></param>
public static void WritingLogs(string strPath, string strContent)
{
FileStream fileStream = null;
StreamWriter streamWriter = null;
try
{
if (!Directory.Exists(strPath))
{
Directory.CreateDirectory(strPath);
}
strPath = string.Format("{0}\\{1}{2}", strPath, DateTime.Now.ToString("yyyy-MM-dd"), ".txt");
fileStream = new FileStream(strPath, FileMode.OpenOrCreate, FileAccess.Write);
streamWriter = new StreamWriter(fileStream);
streamWriter.BaseStream.Seek(0L, SeekOrigin.End);
streamWriter.WriteLine(strContent + "\r\n\r\n--------------------------------------------------------" + DateTime.Now.ToString() + "--------------------------------------------------------\r\n");
streamWriter.Flush();
streamWriter.Close();
fileStream.Close();
}
finally
{
streamWriter.Close();
fileStream.Close();
}
} }
}

LogHelper

Utility.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace WindowsService.Common
{
public class Utility
{
/// <summary>
/// 是否到时间进行执行
/// </summary>
/// <param name="hour">当前时间(小时)</param>
/// <returns>true:时间已到;false:时间未到;</returns>
public static bool TimeOut(string hour)
{
string times = "14|20|01";
if (times == null || times.Trim().Length <= )
{
return false;
}
if (times.IndexOf('|') > )
{
foreach (string t in times.Split('|'))
{
if (t == hour)
{
return true;
}
}
}
else if (times == hour)
{
return true;
}
return false;
}
}
}

Utility

TaskStart.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WindowsService.Common; namespace WindowsService.BusinessServices
{
public class TaskStart
{ /// <summary>
/// 业务开始运行
/// </summary>
public void TaskProcessing()
{
LogHelper.Write("Start", ".....服务正式运行.....");
Thread.Sleep( * * ); //在20秒内进行附加进程
try
{
bool isRun = false; //默认不执行
while (true)
{
string hour = DateTime.Now.ToString("HH"); //获得当前的时间
isRun = Utility.TimeOut(hour) ? true : false;
if (isRun)//判断服务是否运行
{
#region 具体业务 LogHelper.Write("具体业务", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), null, Guid.NewGuid().ToString())); #endregion isRun = false; //已经操作一次
Thread.Sleep( * * ); //休眠 62 分钟 //必须要超过 一个 小时
}
else
{
//睡眠两分钟
Thread.Sleep( * * ); //停止设定时间,精确度比Sleep高
}
}
}
catch (Exception ce)
{
LogHelper.Write("Operation", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), ce, "\r\n\r\n.....服务异常.....\r\n\r\n")); ServiceController service = new ServiceController(new StartService().ServiceName);
service.Stop(); //停止服务
//service.Pause();//暂停服务
//service.Start();//开始服务
}
}
}
}

TaskStart(具体业务)

修改启动服务代码

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WindowsService.BusinessServices;
using WindowsService.Common; namespace WindowsService
{
public partial class StartService : ServiceBase
{
/// <summary>
/// 当前服务是否停止(默认时flase)
/// </summary>
private bool isStop = false; /// <summary>
/// 启动服务
/// </summary>
public StartService()
{
InitializeComponent(); this.CanPauseAndContinue = true;
this.CanStop = true;
isStop = false;
} ///<summary>
///暂停服务
///</summary>
protected override void OnPause()
{
LogHelper.Write("Operation", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), null, "\r\n\r\n.....暂停服务.....\r\n\r\n"));
isStop = true; //服务暂停
} ///<summary>
///恢复服务
///</summary>
protected override void OnContinue()
{
LogHelper.Write("Operation", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), null, "\r\n\r\n.....继续服务.....\r\n\r\n"));
isStop = false; //继续服务
} /// <summary>
/// 服务停止
/// </summary>
protected override void OnStop()
{
LogHelper.Write("Operation", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), null, "\r\n\r\n.....停止服务.....\r\n\r\n"));
isStop = true; //服务停止
} /// <summary>
/// 服务开始运行
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
try
{
//当服务没有停止时,开始具体业务
if (isStop == false)
{
Thread thread = new Thread(new ThreadStart(new TaskStart().TaskProcessing));
thread.Start();
}
}
catch (Exception ce)
{
LogHelper.Write("Error", LogHelper.GetExceptionMessage(MethodBase.GetCurrentMethod(), ce, "\r\n\r\n.....停止服务.....\r\n\r\n"));
}
}
}
}

StartService

、服务安装

新建一个txt文本,输入以下内容,这里的WindowsService.exe 是程序路径,前面的路径是固定的,后面可变。修改txt文件名称为bat批处理文件,新建文本文档.txt——install.bat 。 然后右击 以管理员身份运行   这个批处理文件。这样服务就安装成功了。最后别忘记手动启动下这个服务。

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe  F:\DownLoad\WindowsService\WindowsService\WindowsService\bin\Debug\WindowsService.exe
pause

、服务卸载

和服务安装步骤一样,输入以下内容。然后 以管理员身份运行 即可。

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /u F:\DownLoad\WindowsService\WindowsService\WindowsService\bin\Debug\WindowsService.exe
pause

四、调试

源码地址:https://github.com/RainFate/WindowsServiceDemo/tree/master/WindowsService

C# Windows服务创建安装卸载的更多相关文章

  1. Windows服务的安装卸载及错误查找

    @echo off echo 清理原有服务项. . . %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil /U D:\abc\te ...

  2. WCF 下的windows服务的安装卸载

    安装:启动vs2010(如果是win2008要以管理员来启动)命令:installutil demo.exe 卸载:先在服务里停止这个服务,然后启动vs2010(如果是win2008要以管理员来启动) ...

  3. 通过批处理进行Windows服务的安装/卸载&启动/停止

    安装服务 @echo off set checked=2 set PATHS=%~sdp0 echo 按任意键执行安装……? pause>nul if %checked% EQU 2 ( %PA ...

  4. .net windows 服务创建、安装、卸载和调试

    原文:http://blog.csdn.net/angle860123/article/details/17375895 windows服务应用程序是一种长期运行在操作系统后台的程序,它对于服务器环境 ...

  5. Windows服务一:新建Windows服务、安装、卸载服务

    Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面 ...

  6. Windows服务创建及安装

    Windows服务创建及安装http://www.cnblogs.com/tuyile006/archive/2006/11/27/573654.html

  7. C#操作windows服务,安装、卸载、停止、启动

    public class ServiceUtil { private string _ServiceName = string.Empty; private string _AppName = str ...

  8. 使用InstallUtil对Windows服务进行安装与卸载

    关于Visual Studio 2012中使用InstallUtil对Windows服务进行安装与卸载的文章,在MSDN中的http://msdn.microsoft.com/en-us/librar ...

  9. windows服务创建与管理

    安装windows 服务 C:\Users\chensimin>cd \ C:\>cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 C:\W ...

随机推荐

  1. 阿里云服务器 ECS Jenkins 安装教程

    参考:https://blog.csdn.net/liqing0013/article/details/83930419

  2. React: 认识React

    一.简介 React-Native是Facebook开源的跨平台框架,用于实现前端和原生进行混合开发.React-Native开发可以很好的使用原生UI构建用户界面,与传统的使用WebView相比,不 ...

  3. 【STM32H7教程】第24章 STM32H7的Cache解读(非常重要)

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第24章       STM32H7的Cache解读(非常重要 ...

  4. idea插件备份

  5. PHP】获取客户端(浏览器)信息、获取客户端系统信息、获取服务器信息

    * 获取客户端浏览器信息 * @param null * @author https://blog.jjonline.cn/phptech/168.html * @return string */ f ...

  6. CRF 详细推导、验证实例

    逐帧softmax CRF主要用于序列标注问题,可以简单理解为是给序列中的每一帧都进行分类,既然是分类,很自然想到将这个序列用CNN或者RNN进行编码后,接一个全连接层用softmax激活,如下图所示 ...

  7. Fusionstorage的逻辑架构

    Fusionstorage Fusionstorage的逻辑架构 Mdc:元数据控制,实现对分布式集群的状态控制,以及控制数据分布式规则,数据重建规则等,mdc默认部署在3个节点的zk盘上,形成mdc ...

  8. abp实战-ContosoUniversity Abp版-1运行项目

    1. 去abp官网下载模板工程,当前最新版本是abp5.0,基于.net core 3.0 https://aspnetboilerplate.com/ 项目名称为ContosoAbp 这里使用的是n ...

  9. python凯撒加密

    在密码学中,恺撒密码是一种最简单且最广为人知的加密技术.它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文.例,当偏移量是3的时候,所有的字母A将 ...

  10. JVM中优化指南

    JVM中优化指南 如何将新对象预留在年轻代 如何让大对象进入年老代 如何设置对象进入年老代的年龄 稳定的 Java 堆 VS 动荡的 Java 堆 增大吞吐量提升系统性能 尝试使用大的内存分页 使用非 ...