在很多应用中需要做windows服务来操作数据库等操作,比如
(1)一些非常慢的数据库操作,不想一次性去做,想慢慢的通过服务定时去做,比如定时为数据库备份等
(2)在.net Remoting中利用windows服务来做Host
利用vs.net我们可以在几分钟之内建立其windows服务,非常简单
下面说一下步骤1. 新建一个项目
2. 从一个可用的项目模板列表当中选择Windows服务
3. 设计器会以设计模式打开
4. 从工具箱的组件表当中拖动一个Timer对象到这个设计表面上 (注意: 要确保是从组件列表而不是从Windows窗体列表当中使用Timer)
5. 设置Timer属性,Interval属性200毫秒(1秒进行5次数据库操作)
6. 然后为这个服务填加功能
7.双击这个Timer,然后在里面写一些数据库操作的代码,比如
SqlConnection conn=new SqlConnection("server=127.0.0.1;database=test;uid=sa;pwd=275280");
SqlCommand comm=-new SqlCommand("insert into tb1 ('111',11)",conn);
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
8. 将这个服务程序切换到设计视图
9. 右击设计视图选择“添加安装程序”
10. 切换到刚被添加的ProjectInstaller的设计视图
11. 设置serviceInstaller1组件的属性:
1) ServiceName = My Sample Service
2) StartType = Automatic (开机自动运行)
12. 设置serviceProcessInstaller1组件的属性 Account = LocalSystem
13. 改变路径到你项目所在的bin\Debug文件夹位置(如果你以Release模式编译则在bin\Release文件夹)
14. 执行命令“InstallUtil.exe MyWindowsService.exe”注册这个服务,使它建立一个合适的注册项。(InstallUtil这个程序在WINDOWS文件夹\Microsoft.NET\Framework\v1.1.4322下面)
15. 右击桌面上“我的电脑”,选择“管理”就可以打计算机管理控制台
16. 在“服务和应用程序”里面的“服务”部分里,你可以发现你的Windows服务已经包含在服务列表当中了
17. 右击你的服务选择启动就可以启动你的服务了
看看数据库是不是一秒多了5个记录啊
需要注意的是:
如果你修改了这个服务,路径没有变化的话是不需要重新注册服务的,如果路径发生了变化,需要先卸载这个服务InstallUtil.exe /u参数,然后再重新安装这个服务,不能直接安装。还有就是windows服务是没有界面的,不要企图用控制的输出方式来输出一些信息,你只能添加一个EventLog,通过WriteEntry()来写日志。
关于怎么用windows服务来做一个远程服务可以看一下http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT15.asp
问题
用以上说的建立了一个服务,启动后,timer却不起作用,sql不执行,不知道为什么?服务都是顺利启动的,但却不执行任务?
可以在 OnStart() 方法里加上 this.timer1.Enabled = true;
另外看一下this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed); 是否和你的事件关联上
如何实现可插拔的windows服务
如果只是实现普通需求非常容易,可以参考文章里的那几个blog。但是如果要做为一个企业级的应用,往往会有别的场景需求。这里描述了能在不改变系统结构的情况下,可以非常快速的支持新的服务要求,并且以多线程方式支持多种业务逻辑的weindows服务开发方法,最后是一些调试技巧。
这是一个安装和卸载服务的类,有兴趣可以看一下.
using
System;
using
System.Runtime.InteropServices;
namespace
EAE.MyServiceInstaller
{
class
ServiceInstaller
{
#region
Private Variables
private
string
_servicePath;
private
string
_serviceName;
private
string
_serviceDisplayName;
#endregion
Private Variables
#region
DLLImport
[DllImport(
"
advapi32.dll
"
)]
public
static
extern
IntPtr OpenSCManager(
string
lpMachineName,
string
lpSCDB,
int
scParameter);
[DllImport(
"
Advapi32.dll
"
)]
public
static
extern
IntPtr CreateService(IntPtr SC_HANDLE,
string
lpSvcName,
string
lpDisplayName,
int
dwDesiredAccess,
int
dwServiceType,
int
dwStartType,
int
dwErrorControl,
string
lpPathName,
string
lpLoadOrderGroup,
int
lpdwTagId,
string
lpDependencies,
string
lpServiceStartName,
string
lpPassword);
[DllImport(
"
advapi32.dll
"
)]
public
static
extern
void
CloseServiceHandle(IntPtr SCHANDLE);
[DllImport(
"
advapi32.dll
"
)]
public
static
extern
int
StartService(IntPtr SVHANDLE,
int
dwNumServiceArgs,
string
lpServiceArgVectors);
[DllImport(
"
advapi32.dll
"
,SetLastError
=
true
)]
public
static
extern
IntPtr OpenService(IntPtr SCHANDLE,
string
lpSvcName,
int
dwNumServiceArgs);
[DllImport(
"
advapi32.dll
"
)]
public
static
extern
int
DeleteService(IntPtr SVHANDLE);
[DllImport(
"
kernel32.dll
"
)]
public
static
extern
int
GetLastError();
#endregion
DLLImport
//
//
/
//
//
/ 应用程序入口.
//
//
/
//
//
[STAThread]
//
static void Main(string[] args)
//
{
//
//
string svcPath;
//
string svcName;
//
string svcDispName;
//
//
服务程序的路径
//
svcPath = @"d:\service\EAEWS.exe";
//
svcDispName="myEAEWS";
//
svcName= "myEAEWS";
//
ServiceInstaller c = new ServiceInstaller();
//
c.InstallService(svcPath, svcName, svcDispName);
//
Console.Read();
//
//
}
///
///
安装和运行
///
///
程序路径.
///
服务名
///
服务显示名称.
///
服务安装是否成功.
public
bool
InstallService(
string
svcPath,
string
svcName,
string
svcDispName)
{
#region
Constants declaration.
int
SC_MANAGER_CREATE_SERVICE
=
0x0002
;
int
SERVICE_WIN32_OWN_PROCESS
=
0x00000010
;
//
int SERVICE_DEMAND_START = 0x00000003;
int
SERVICE_ERROR_NORMAL
=
0x00000001
;
int
STANDARD_RIGHTS_REQUIRED
=
0xF0000
;
int
SERVICE_QUERY_CONFIG
=
0x0001
;
int
SERVICE_CHANGE_CONFIG
=
0x0002
;
int
SERVICE_QUERY_STATUS
=
0x0004
;
int
SERVICE_ENUMERATE_DEPENDENTS
=
0x0008
;
int
SERVICE_START
=
0x0010
;
int
SERVICE_STOP
=
0x0020
;
int
SERVICE_PAUSE_CONTINUE
=
0x0040
;
int
SERVICE_INTERROGATE
=
0x0080
;
int
SERVICE_USER_DEFINED_CONTROL
=
0x0100
;
int
SERVICE_ALL_ACCESS
=
(STANDARD_RIGHTS_REQUIRED
|
SERVICE_QUERY_CONFIG
|
SERVICE_CHANGE_CONFIG
|
SERVICE_QUERY_STATUS
|
SERVICE_ENUMERATE_DEPENDENTS
|
SERVICE_START
|
SERVICE_STOP
|
SERVICE_PAUSE_CONTINUE
|
SERVICE_INTERROGATE
|
SERVICE_USER_DEFINED_CONTROL);
int
SERVICE_AUTO_START
=
0x00000002
;
#endregion
Constants declaration.
try
{
IntPtr sc_handle
=
OpenSCManager(
null
,
null
,SC_MANAGER_CREATE_SERVICE);
if
(sc_handle.ToInt32()
!=
0
)
{
IntPtr sv_handle
=
CreateService(sc_handle,svcName,svcDispName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,svcPath,
null
,
0
,
null
,
null
,
null
);
if
(sv_handle.ToInt32()
==
0
)
{
CloseServiceHandle(sc_handle);
return
false
;
}
else
{
//
试尝启动服务
int
i
=
StartService(sv_handle,
0
,
null
);
if
(i
==
0
)
{
return
false
;
}
CloseServiceHandle(sc_handle);
return
true
;
}
}
else
return
false
;
}
catch
(Exception e)
{
throw
e;
}
}
///
///
反安装服务.
///
///
服务名.
public
bool
UnInstallService(
string
svcName)
{
int
GENERIC_WRITE
=
0x40000000
;
IntPtr sc_hndl
=
OpenSCManager(
null
,
null
,GENERIC_WRITE);
if
(sc_hndl.ToInt32()
!=
0
)
{
int
DELETE
=
0x10000
;
IntPtr svc_hndl
=
OpenService(sc_hndl,svcName,DELETE);
if
(svc_hndl.ToInt32()
!=
0
)
{
int
i
=
DeleteService(svc_hndl);
if
(i
!=
0
)
{
CloseServiceHandle(sc_hndl);
return
true
;
}
else
{
CloseServiceHandle(sc_hndl);
return
false
;
}
}
else
return
false
;
}
else
return
false
;
}
}
}
我用C#写了一个服务,用定时器定时检测,不符合某个条件我就退出服务。
下面的示例使用 ServiceController 类检查 Telnet 服务的当前状态。如果该服务已停止,此示例将启动该服务。如果该服务正在运行,此示例将停止该服务。
//
Toggle the Telnet service -
//
If it is started (running, paused, etc), stop the service.
//
If it is stopped, start the service.
ServiceController sc
=
new
ServiceController(
"
Telnet
"
);
Console.WriteLine(
"
The Telnet service status is currently set to {0}
"
,
sc.Status.ToString());
if
((sc.Status.Equals(ServiceControllerStatus.Stopped))
||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
//
Start the service if the current status is stopped.
Console.WriteLine(
"
Starting the Telnet service
"
);
sc.Start();
}
else
{
//
Stop the service if its status is not set to "Stopped".
Console.WriteLine(
"
Stopping the Telnet service
"
);
sc.Stop();
}
//
Refresh and display the current service status.
sc.Refresh();
Console.WriteLine(
"
The Telnet service status is now set to {0}.
"
, sc.Status.ToString());
Windows服务开发相关文章收集
总结
最近公司要我做这个,我看了相关的文章,便整理了一下.
实践的时候也出现了服务不执行操作的现象,希望大家一起共同探讨一下,相互学习.