1、Windows Service 服务创建
服务创建内容就不在说明,网上资料挺多
2、Timer
在Windows Server中使用Timer 必须使用System.Timers空间下Timer ,不然Timer将不起作用
注意:貌似在Windows Service中不能使用Task ,经测试使用Task后 安装程序不能启动服务,一直提示没有权限启动服务。
3、安装启动
要在安装的时候启动服务,需要在做安装包的时候进行设置,后面说明服务安装包制作
4、调用可操作界面程序
IntPtr userTokenHandle = IntPtr.Zero;
ApiDefinitions.WTSQueryUserToken(ApiDefinitions.WTSGetActiveConsoleSessionId(), ref userTokenHandle);
ApiDefinitions.PROCESS_INFORMATION procInfo = new ApiDefinitions.PROCESS_INFORMATION();
ApiDefinitions.STARTUPINFO startInfo = new ApiDefinitions.STARTUPINFO();
startInfo.cb = (uint)System.Runtime.InteropServices.Marshal.SizeOf(startInfo);
ApiDefinitions.CreateProcessAsUser(
userTokenHandle,
startPath,//要启动的程序
"",
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
null,
ref startInfo,
out procInfo);
if (userTokenHandle != IntPtr.Zero)
ApiDefinitions.CloseHandle(userTokenHandle);
int _currentAquariusProcessId = (int)procInfo.dwProcessId;
需要下载Cjwdev.WindowsApi的一个Dll,至于为什么这样用我也不晓得,反正很多都说这样用,
注意:
1、这里如果你的启动程序需要传递参数,目前用这个方法不知道怎么弄,可以使用中转程序来完成,该服务启动中转程序,中转程序设置参数启动最终应用。
2、如果需要在开机启动服务,并且启动服务后需要显示一个窗体,需要在设置CanHandleSessionChangeEvent属性为True来监听系统消息事件;并添加下面函数对系统消息进行处理;由于服务启动的顺序不随机,要想在开机保证一个界面正确显示需要在服务启动的时候调用窗体程序(有可能该服务在系统登陆后才启动,因此服务启动后就要调用窗体程序),并且在SessionChangeReason.SessionLogon:时候调用窗体程序(有可能服务启动在用户登陆成功之前,这样在启动服务时候调用的窗体将显示不出来,所以需要在这个事件后再调用一下窗体显示程序),通过在服务启动和系统登陆成功时均调用窗体启动程序才能保证窗体程序能够正确的在开机时候进行显示。
protected override void OnSessionChange(SessionChangeDescription Description)
{
try
{
switch (Description.Reason)
{
case SessionChangeReason.ConsoleConnect:
break;
case SessionChangeReason.ConsoleDisconnect:
break;
case SessionChangeReason.RemoteConnect:
break;
case SessionChangeReason.RemoteDisconnect:
break;
case SessionChangeReason.SessionLock:
break;
case SessionChangeReason.SessionLogoff:
break;
case SessionChangeReason.SessionLogon://用户开机后首次登陆系统
break;
case SessionChangeReason.SessionRemoteControl:
break;
case SessionChangeReason.SessionUnlock:
break;
default:
break;
}
}
catch (Exception ex)
{
LogMan.Logger.Error(ex);
}
}
5、数据库查询
本人测试要在Window Serveice服务中访问数据库或者是在通过系统启动服务,在服务里去调用的程序访问数据库,不能使用EF框架,目前测试的是vs 2013 服务使用EF SqlLite去访问数据库,就是报错,具体原因不详。