Windows服务可以用于创建定时任务,在规定时间内执行特定的程序。比如在早上9点到下午5点调用第三方接口获取数据,就可以使用Windows服务来完成操作。
参考文章:
https://wwwblogs/cncc/p/7170951.html
https://wwwblogs/buchizaodian/p/6160816.html
1.在vs中新建一个项目,选择Windows服务:
创建的项目结构,如下图所示:
2.为服务添加安装程序
点击service1.cs,然后在左侧界面中右击,选择‘添加按照程序’。
点击后会生成如下文件:
同时会生成两个组件,分别为“serviceInstaller1”及“serviceProcessInstaller1”
鼠标选中第二个(serviceInstaller1),然后右键,选择属性:
在属性窗口中可以对服务做一些配置,比如修改服务名称等等。其他的配置可以根据需要自行配置。
serviceInstaller1的属性
Name:表示控件的名称
Description:是安装后描述的名字
DisplayName:显示的名称
ServiceName:指示系统用于标识此服务的名称。此属性必须与要安装的服务的 ServiceBase.ServiceName 相同
StartType:
表示服务的启动方式。默认为 Manual,指定在重新启动后服务将不会自动启动。Automatic:自动启动。Disabled:禁用
设置 StartType 来指定该服务是在重新启动后自动启动,还是必须由用户手动启动。服务还可以被禁用,指定在启用以前不能被手动或以编程方式启动。
更多详细配置信息参考:https://docs.microsoft/zh-cn/dotnet/api/system.serviceprocess.serviceinstaller?redirectedfrom=MSDN&view=netframework-4.8#properties
serviceProcessInstaller1的属性
Account:获取或设置运行该服务应用程序时所使用的帐户类型
LocalService:充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器。
NetworkService:提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器。
LocalSystem:服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机。
User:由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值。
更多详细配置信息参考:https://msdn.microsoft/zh-cn/library/system.serviceprocess.serviceprocessinstaller_properties(v=vs.80).aspx
3.新建测试类TestClass,模拟业务逻辑处理代码。
4.添加测试代码和测试窗口,便于程序调试,新建一个Windows窗体
然后在窗体中添加一个按钮,并绑定事件:
5.在Program.cs文件中把自动生成的代码注释,然后加上如下代码:
发布到生产环境还是要用上面的代码,添加的这段代码仅仅是为了调试用。
这时候启动项目,就会弹出刚才添加的窗体:
点击开始按钮,程序就会进入断点位置,可以对代码进行调试。
6.代码编写完成后,编译程序,会在项目的bin文件中生生成对应工程名的exe文件。
双击运行弹出如下提示:
解决方法参考:https://wwwblogs/buchizaodian/p/6160816.html
https://jingyan.baidu/article/fa4125acb71a8628ac709226.html
控制服务的运行时间和运行频率:
在App.config文件中加如下配置
<connectionStrings>
<!--服务开启时间-->
<add name="ServiceStart" connectionString="9:00"/>
<!--服务执行间隔(秒)-->
<add name="ServiceInterval" connectionString="60"/>
<!--服务停止时间-->
<add name="ServiceEnd" connectionString="17:00"/>
<!--服务是否开启(1开启、0关闭)-->
<add name="ServiceIsOn" connectionString="0"/>
</connectionStrings>
在Service1.cs中添加代码:
public partial class Service1 : ServiceBase
{
//服务配置项
private static string ServiceStart = ConfigurationManager.ConnectionStrings["ServiceStart"].ConnectionString;
private static int ServiceInterval = Convert.ToInt32(ConfigurationManager.ConnectionStrings["ServiceInterval"].ConnectionString);
private static string ServiceEnd = ConfigurationManager.ConnectionStrings["ServiceEnd"].ConnectionString;
private static string ServiceIsOn = ConfigurationManager.ConnectionStrings["ServiceIsOn"].ConnectionString;
//服务定时器
private System.Timers.Timer timer = new System.Timers.Timer();
public Service1()
{
InitializeComponent();
}
/// <summary>
/// 开启服务
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
if (ServiceIsOn == "1")
{
timer.Enabled = true;
timer.Interval = ServiceInterval * 1000;//执行间隔时间,单位为毫秒; 这里实际间隔为1秒钟
timer.Start();
timer.Elapsed += new System.Timers.ElapsedEventHandler(Procedure_Timer);
Procedure_Timer(null, null);
}
}
/// <summary>
/// 定时器执行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Procedure_Timer(object sender, System.Timers.ElapsedEventArgs e)
{
timer.Enabled = false;
TestClass service = new TestClass();
DateTime newDate = DateTime.Now;
//获取当前时间
int intHour = newDate.Hour;
int intMinute = newDate.Minute;
//开始时间
string[] startStamp = ServiceStart.Split(':');
int startHour = Convert.ToInt32(startStamp[0]);
int startMinute = Convert.ToInt32(startStamp[1]);
//结束时间
string[] endStamp = ServiceEnd.Split(':');
int endHour = Convert.ToInt32(endStamp[0]);
int endMinute = Convert.ToInt32(endStamp[1]);
int newTime = (intHour * 100) + intMinute;
int startTime = (startHour * 100) + startMinute;
int endTime = (endHour * 100) + endMinute;
// 每天定点在一个时间段内执行
if (newTime >= startTime && newTime <= endTime)
{
//执行业务代码
service.procedureStart();
}
timer.Enabled = true;
}
/// <summary>
/// 关闭服务
/// </summary>
protected override void OnStop()
{
timer.Stop();
}
}
这样就可以通过配置文件控制服务运行的时间。