转自: https://wenku.baidu.com/view/5e92ae02763231126edb1163.html
在Visual Studio中创建WindowsService过程
- 新建一个服务
- 添加代码
vs会自动生成一些代码
在Service1.cs中会看到如下代码
namespace WindowsService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
}
其中OnStart为启动服务时调用的方法;OnStop为停止服务时调用的方法。
每个服务都还有其他方法,比如暂停、恢复等,可以重载基类的方法来实现,如暂停
自己的业务逻辑就可以在这些方法中调用实现。、
ps:在做windows服务时常常是要弄一个循环还处理某些业务逻辑,常见的方法是用一个Timer控件,值得注意的是Toolbox中的Timer控件默认是System.Windows.Forms.Timer,显然在这里是不会起作用的,这里可用System.Timers.Timer,可以直接在Toolbox中右键添加。
- 添加Installer
这一步很关键,在处理完业务逻辑后需添加一个Installer才能使你的windows服务能够被安装。
在VS中添加Installer也很简单,操作如下:
右键Service1.cs,选择装换为视图界面
再到View Desiger视图中右键,选择添加安装程序
Installer就添加好了。
4. 设置服务参数
可以在程序中先给定windows服务的参数
在添加Installer时会自动生成一个ProjectInstaller.cs,在这个文件中有个InitializeComponent方法,如下:
namespace WindowsService
{
partial class ProjectInstaller
{
/// <summary>
/// 必?需è的?设Θ?计?器÷变?量?。£
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清?理え?所ù有瓺正y在ú使?用?的?资哩?源′。£
/// </summary>
/// <param name="disposing">如?果?应畖释酣?放?托狣管ü资哩?源′,?为a true;?否?则ò为a false。£</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组哩?件t设Θ?计?器÷生Θ?成é的?代洙?码?
/// <summary>
/// 设Θ?计?器÷支§持?所ù需è的?方?法ぁ?- 不?要癮
/// 使?用?代洙?码?编括?辑-器÷修T改?此?方?法ぁ?的?内ú容╕。£
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
//
// serviceInstaller1
//
this.serviceInstaller1.ServiceName = "Service1";
this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall);
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
#endregion
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
}
}
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
为设置服务的登陆账号密码,如果不想设置用户名密码也可以采用本地系统帐户运行服务,代码如下:
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
其他设置也可在此完成。
- 安装和卸载windows服务
制作完成的windows服务发布后为一个exe文件,要想到目标机器上安装使用这个服务,可以用微软提供的installutil工具,通过命令行的方式实现安装和卸载。
installutil工具在目录:系统盘:\WINDOWS\Microsoft.NET\Framework\v4.0.30319下,运行cmd,输入
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil xxxx.exe 回车,即可完成windows服务的安装。
卸载则为输入 C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil /u xxxx.exe 回车。
ps:可以保存为bat文件执行则更为方便。
注意:
我们用InstallUtil.exe安装服务,在我们系统中可能有两个文件夹都包含InstallUtil.exe,在我的电脑中有如下两个文件夹(当然,我选择的是.NET平台4.0版本):
- C:\Windows\Microsoft.NET\Framework\v4.0.30319
- C:\Windows\Microsoft.NET\Framework64\v4.0.30319
我们在默认情况下生成服务程序之后,如果我们使用2路径下的InstallUtil.exe安装,则会报
System.BadImageFormatException异常。可以将其改成any cpu环境,步骤:生成---> 配置管理器--->平台选择any cpu。但是这样做之后,对后面访问数据库等操作造成影响,不建议使用。
那么,我们最简单易行的方法就是:在默认VS平台生成环境下,用1路径下的InstallUtil.exe安装服务
ServiceProcessInstaller的属性Account默认值为user,这会在安装服务时,弹出对话框信息,要求用户名和密码。如果没有指定正确,麻烦来了,并且你怎么也不会想到异常来自于这里。Exception信息是:
在“安装”阶段发生异常。
System.ArgumentOutOfRangeException: 索引和长度必须引用该字符串内的位置。
参数名: length
解决:将它设置成LocalSystem就可以工作了.