以前做项目写了个Widows服务程序,当时为了赶时间找了几篇文章学习了下就匆匆搞定交差。
这段时间程序出了些小BUG,把工程打开几下就找到了问题,修改好后安装运行OK了!但还是有美中不足的地方(追求完美),服务程序没有描述,而且启动失败后计算机的反应等也没有设置。开始以为很简单,无非是设置一个类似于Name,Description的属性,结果找半天也没找到,于是就打开了Google开始了在知识的海洋中遨游。。。功夫不负苦心人,终于被我找到了,改了下,一试成功!!!代码如下:
原来要调用非托管代码才能实现,真不知道MS在搞什么?似乎是为了抢占市场半成品就拿出来给大家用了。。。
非托管代码调用接口类 modAPI.cs

modAPI
1
using System;
2
using System.Runtime.InteropServices;
3
4
namespace ScanSMSService
5

{
6
/**//// <summary>
7
/// modAPI 的摘要说明。
8
/// </summary>
9
public class modAPI
10
{
11
public modAPI()
12
{
13
//
14
// TODO: 在此处添加构造函数逻辑
15
//
16
}
17
[DllImport("advapi32.dll")]
18
public static extern int LockServiceDatabase(int hSCManager);
19
20
[DllImport("advapi32.dll")]
21
public static extern bool UnlockServiceDatabase(int hSCManager);
22
23
[DllImport("kernel32.dll")]
24
public static extern void CopyMemory(IntPtr pDst, SC_ACTION[] pSrc,int ByteLen);
25
26
[DllImport("advapi32.dll")]
27
public static extern bool ChangeServiceConfigA(
28
int hService, ServiceType dwServiceType, int dwStartType,
29
int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup,
30
int lpdwTagId, string lpDependencies, string lpServiceStartName,
31
string lpPassword, string lpDisplayName);
32
33
[DllImport("advapi32.dll")]
34
public static extern bool ChangeServiceConfig2A(
35
int hService, InfoLevel dwInfoLevel,
36
[MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);
37
38
[DllImport("advapi32.dll")]
39
public static extern bool ChangeServiceConfig2A(
40
int hService, InfoLevel dwInfoLevel,
41
[MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo);
42
43
[DllImport("advapi32.dll")]
44
public static extern int OpenServiceA(
45
int hSCManager, string lpServiceName, ACCESS_TYPE dwDesiredAccess);
46
47
[DllImport("advapi32.dll")]
48
public static extern int OpenSCManagerA(
49
string lpMachineName, string lpDatabaseName, ServiceControlManagerType dwDesiredAccess);
50
51
[DllImport("advapi32.dll")]
52
public static extern bool CloseServiceHandle(
53
int hSCObject);
54
55
[DllImport("advapi32.dll")]
56
public static extern bool QueryServiceConfigA(
57
int hService, [MarshalAs(UnmanagedType.Struct)] ref QUERY_SERVICE_CONFIG lpServiceConfig, int cbBufSize,
58
int pcbBytesNeeded);
59
[DllImport("advapi32.dll")]
60
public static extern int StartService(int SVHANDLE,int dwNumServiceArgs,string lpServiceArgVectors);
61
62
public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
63
public const int GENERIC_READ = -2147483648;
64
public const int ERROR_INSUFFICIENT_BUFFER = 122;
65
public const int SERVICE_NO_CHANGE = -1;
66
//public const int SERVICE_NO_CHANGE = 0xFFFF;
67
68
public enum ServiceType
69
{
70
SERVICE_KERNEL_DRIVER = 0x1,
71
SERVICE_FILE_SYSTEM_DRIVER = 0x2,
72
SERVICE_WIN32_OWN_PROCESS = 0x10,
73
SERVICE_WIN32_SHARE_PROCESS = 0x20,
74
SERVICE_INTERACTIVE_PROCESS = 0x100,
75
SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE
76
}
77
78
public enum ServiceStartType:int
79
{
80
SERVICE_BOOT_START = 0x0,
81
SERVICE_SYSTEM_START = 0x1,
82
SERVICE_AUTO_START = 0x2,
83
SERVICE_DEMAND_START = 0x3,
84
SERVICE_DISABLED = 0x4,
85
SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE
86
}
87
88
public enum ServiceErrorControl:int
89
{
90
SERVICE_ERROR_IGNORE = 0x0,
91
SERVICE_ERROR_NORMAL = 0x1,
92
SERVICE_ERROR_SEVERE = 0x2,
93
SERVICE_ERROR_CRITICAL = 0x3,
94
msidbServiceInstallErrorControlVital = 0x8000,
95
SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE
96
}
97
98
public enum ServiceStateRequest:int
99
{
100
SERVICE_ACTIVE = 0x1,
101
SERVICE_INACTIVE = 0x2,
102
SERVICE_STATE_ALL = (SERVICE_ACTIVE + SERVICE_INACTIVE)
103
}
104
105
public enum ServiceControlType:int
106
{
107
SERVICE_CONTROL_STOP = 0x1,
108
SERVICE_CONTROL_PAUSE = 0x2,
109
SERVICE_CONTROL_CONTINUE = 0x3,
110
SERVICE_CONTROL_INTERROGATE = 0x4,
111
SERVICE_CONTROL_SHUTDOWN = 0x5,
112
SERVICE_CONTROL_PARAMCHANGE = 0x6,
113
SERVICE_CONTROL_NETBINDADD = 0x7,
114
SERVICE_CONTROL_NETBINDREMOVE = 0x8,
115
SERVICE_CONTROL_NETBINDENABLE = 0x9,
116
SERVICE_CONTROL_NETBINDDISABLE = 0xA,
117
SERVICE_CONTROL_DEVICEEVENT = 0xB,
118
SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC,
119
SERVICE_CONTROL_POWEREVENT = 0xD,
120
SERVICE_CONTROL_SESSIONCHANGE = 0xE,
121
}
122
123
public enum ServiceState:int
124
{
125
SERVICE_STOPPED = 0x1,
126
SERVICE_START_PENDING = 0x2,
127
SERVICE_STOP_PENDING = 0x3,
128
SERVICE_RUNNING = 0x4,
129
SERVICE_CONTINUE_PENDING = 0x5,
130
SERVICE_PAUSE_PENDING = 0x6,
131
SERVICE_PAUSED = 0x7,
132
}
133
134
public enum ServiceControlAccepted:int
135
{
136
SERVICE_ACCEPT_STOP = 0x1,
137
SERVICE_ACCEPT_PAUSE_CONTINUE = 0x2,
138
SERVICE_ACCEPT_SHUTDOWN = 0x4,
139
SERVICE_ACCEPT_PARAMCHANGE = 0x8,
140
SERVICE_ACCEPT_NETBINDCHANGE = 0x10,
141
SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x20,
142
SERVICE_ACCEPT_POWEREVENT = 0x40,
143
SERVICE_ACCEPT_SESSIONCHANGE = 0x80
144
}
145
146
public enum ServiceControlManagerType:int
147
{
148
SC_MANAGER_CONNECT = 0x1,
149
SC_MANAGER_CREATE_SERVICE = 0x2,
150
SC_MANAGER_ENUMERATE_SERVICE = 0x4,
151
SC_MANAGER_LOCK = 0x8,
152
SC_MANAGER_QUERY_LOCK_STATUS = 0x10,
153
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x20,
154
SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SC_MANAGER_CONNECT + SC_MANAGER_CREATE_SERVICE + SC_MANAGER_ENUMERATE_SERVICE + SC_MANAGER_LOCK + SC_MANAGER_QUERY_LOCK_STATUS + SC_MANAGER_MODIFY_BOOT_CONFIG
155
}
156
157
public enum ACCESS_TYPE:int
158
{
159
SERVICE_QUERY_CONFIG = 0x1,
160
SERVICE_CHANGE_CONFIG = 0x2,
161
SERVICE_QUERY_STATUS = 0x4,
162
SERVICE_ENUMERATE_DEPENDENTS = 0x8,
163
SERVICE_START = 0x10,
164
SERVICE_STOP = 0x20,
165
SERVICE_PAUSE_CONTINUE = 0x40,
166
SERVICE_INTERROGATE = 0x80,
167
SERVICE_USER_DEFINED_CONTROL = 0x100,
168
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
169
}
170
171
[StructLayout(LayoutKind.Sequential)]
172
public struct SERVICE_STATUS
173
{
174
public int dwServiceType;
175
public int dwCurrentState;
176
public int dwControlsAccepted;
177
public int dwWin32ExitCode;
178
public int dwServiceSpecificExitCode;
179
public int dwCheckPoint;
180
public int dwWaitHint;
181
}
182
183
[StructLayout(LayoutKind.Sequential)]
184
public struct QUERY_SERVICE_CONFIG
185
{
186
public int dwServiceType;
187
public int dwStartType;
188
public int dwErrorControl;
189
public string lpBinaryPathName;
190
public string lpLoadOrderGroup;
191
public int dwTagId;
192
public string lpDependencies;
193
public string lpServiceStartName;
194
public string lpDisplayName;
195
}
196
197
public enum SC_ACTION_TYPE:int
198
{
199
SC_ACTION_NONE = 0,
200
SC_ACTION_RESTART = 1,
201
SC_ACTION_REBOOT = 2,
202
SC_ACTION_RUN_COMMAND = 3,
203
}
204
205
[StructLayout(LayoutKind.Sequential)]
206
public struct SC_ACTION
207
{
208
public SC_ACTION_TYPE SCActionType;
209
public int Delay;
210
}
211
public enum InfoLevel:int
212
{
213
SERVICE_CONFIG_DESCRIPTION = 1,
214
SERVICE_CONFIG_FAILURE_ACTIONS = 2
215
}
216
217
[StructLayout(LayoutKind.Sequential)]
218
public struct SERVICE_DESCRIPTION
219
{
220
public string lpDescription;
221
}
222
223
[StructLayout(LayoutKind.Sequential)]
224
public struct SERVICE_FAILURE_ACTIONS
225
{
226
public int dwResetPeriod;
227
public string lpRebootMsg;
228
public string lpCommand;
229
public int cActions;
230
public int lpsaActions;
231
}
232
}
233
}
234
235
服务程序安装类 ProjectInstaller.cs

ProjectInstaller
1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Configuration.Install;
5
using System.Runtime.InteropServices;
6
7
namespace ScanSMSService
8

{
9
/**//// <summary>
10
/// ProjectInstaller 的摘要说明。
11
/// </summary>
12
[RunInstaller(true)]
13
public class ProjectInstaller : System.Configuration.Install.Installer
14
{
15
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
16
private System.ServiceProcess.ServiceInstaller ScanSMSServiceInstaller;
17
/**//// <summary>
18
/// 必需的设计器变量。
19
/// </summary>
20
private System.ComponentModel.Container components = null;
21
22
public ProjectInstaller()
23
{
24
// 该调用是设计器所必需的。
25
InitializeComponent();
26
// TODO: 在 InitializeComponent 调用后添加任何初始化
27
this.Committed+=new InstallEventHandler(ProjectInstaller_Committed);
28
this.AfterInstall += new InstallEventHandler(ProjectInstaller_AfterInstall);
29
30
}
31
32
/**//// <summary>
33
/// 清理所有正在使用的资源。
34
/// </summary>
35
protected override void Dispose( bool disposing )
36
{
37
if( disposing )
38
{
39
if(components != null)
40
{
41
components.Dispose();
42
}
43
}
44
base.Dispose( disposing );
45
}
46
47
48
组件设计器生成的代码#region 组件设计器生成的代码
49
/**//// <summary>
50
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
51
/// 此方法的内容。
52
/// </summary>
53
private void InitializeComponent()
54
{
55
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
56
this.ScanSMSServiceInstaller = new System.ServiceProcess.ServiceInstaller();
57
//
58
// serviceProcessInstaller1
59
//
60
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
61
this.serviceProcessInstaller1.Password = null;
62
this.serviceProcessInstaller1.Username = null;
63
//
64
// ScanSMSServiceInstaller
65
//
66
this.ScanSMSServiceInstaller.DisplayName = "短信扫描程序";
67
this.ScanSMSServiceInstaller.ServiceName = "ScanSMSService";
68
this.ScanSMSServiceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
69
//
70
// ProjectInstaller
71
//
72
this.Installers.AddRange(new System.Configuration.Install.Installer[]
{
73
this.serviceProcessInstaller1,
74
this.ScanSMSServiceInstaller});
75
76
}
77
#endregion
78
79
80
private void ProjectInstaller_AfterInstall(object sender,System.Configuration.Install.InstallEventArgs e)
81
{
82
83
int iSCManagerHandle = 0;
84
int iSCManagerLockHandle = 0;
85
int iServiceHandle = 0;
86
bool bChangeServiceConfig = false;
87
bool bChangeServiceConfig2 = false;
88
89
modAPI.SERVICE_DESCRIPTION ServiceDescription;
90
modAPI.SERVICE_FAILURE_ACTIONS ServiceFailureActions;
91
modAPI.SC_ACTION[] ScActions = new modAPI.SC_ACTION[3];
92
93
bool bCloseService = false;
94
bool bUnlockSCManager = false;
95
bool bCloseSCManager = false;
96
97
IntPtr iScActionsPointer = new IntPtr();
98
99
try
100
{
101
//打开服务控制台
102
iSCManagerHandle = modAPI.OpenSCManagerA(null, null, modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS);
103
104
if (iSCManagerHandle < 1)
105
{
106
throw new Exception("不能打开服务管理器.");
107
}
108
109
iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle);
110
111
112
if (iSCManagerLockHandle < 1)
113
{
114
throw new Exception("不能锁定服务管理器.");
115
}
116
117
//根据服务名"ScanSMSService",获得句柄
118
iServiceHandle = modAPI.OpenServiceA(iSCManagerHandle, "ScanSMSService",modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS);
119
if (iServiceHandle < 1)
120
{
121
throw new Exception("不能打开服务进行修改.");
122
}
123
124
bChangeServiceConfig = modAPI.ChangeServiceConfigA(iServiceHandle,
125
modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS | modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS,
126
modAPI.SERVICE_NO_CHANGE, modAPI.SERVICE_NO_CHANGE, null, null,
127
0, null, null, null, null);
128
129
130
if (bChangeServiceConfig==false)
131
{
132
throw new Exception("不能改变服务设置.");
133
}
134
//短信扫描服务,如果停止该服务,短信将不能发送!
135
ServiceDescription.lpDescription = "";
136
137
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION,ref ServiceDescription);
138
139
if (bChangeServiceConfig2==false)
140
{
141
throw new Exception("不能进行服务描述更改.");
142
}
143
144
ServiceFailureActions.dwResetPeriod = 600;
145
ServiceFailureActions.lpRebootMsg = "服务启动失败! 重启中
";
146
// ServiceFailureActions.lpCommand = "SomeCommand.exe Param1 Param2";
147
ServiceFailureActions.lpCommand = "";
148
ServiceFailureActions.cActions = ScActions.Length;
149
150
//故障恢复设置,这里没有设置
151
ScActions[0].Delay = 20000;
152
//不要对失败操作做任何处理,如重启服务等
153
ScActions[0].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE; //什么都不做
154
ScActions[1].Delay = 20000;
155
ScActions[1].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE;
156
ScActions[2].Delay = 20000;
157
ScActions[2].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE;
158
159
iScActionsPointer = Marshal.AllocHGlobal(Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);
160
161
modAPI.CopyMemory(iScActionsPointer, ScActions, Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);
162
ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32();
163
164
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,
165
modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS,ref ServiceFailureActions);
166
167
if (bChangeServiceConfig2==false)
168
{
169
throw new Exception("不能设置服务的故障恢复设置.");
170
}
171
172
}
173
catch(Exception ex)
174
{
175
throw new Exception(ex.Message);
176
}
177
finally
178
{
179
180
Marshal.FreeHGlobal(iScActionsPointer);
181
if (iServiceHandle > 0)
182
{
183
bCloseService = modAPI.CloseServiceHandle(iServiceHandle);
184
}
185
if (iSCManagerLockHandle > 0)
186
{
187
bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle);
188
}
189
if (iSCManagerHandle != 0)
190
{
191
bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle);
192
}
193
}
194
}
195
private void ProjectInstaller_Committed(object sender, InstallEventArgs e)
196
{
197
//Do Nothing
198
}
199
}
200
}
201
参考文章:http://doc.chinahtml.com/Manual/asp.net/dot42.htm
http://www.xker.com/Html/windows/2006_04_12_10_568.html
这段时间程序出了些小BUG,把工程打开几下就找到了问题,修改好后安装运行OK了!但还是有美中不足的地方(追求完美),服务程序没有描述,而且启动失败后计算机的反应等也没有设置。开始以为很简单,无非是设置一个类似于Name,Description的属性,结果找半天也没找到,于是就打开了Google开始了在知识的海洋中遨游。。。功夫不负苦心人,终于被我找到了,改了下,一试成功!!!代码如下:
原来要调用非托管代码才能实现,真不知道MS在搞什么?似乎是为了抢占市场半成品就拿出来给大家用了。。。
非托管代码调用接口类 modAPI.cs
1
using System;2
using System.Runtime.InteropServices;3

4
namespace ScanSMSService5


{6

/**//// <summary>7
/// modAPI 的摘要说明。8
/// </summary>9
public class modAPI10

{11
public modAPI()12

{13
//14
// TODO: 在此处添加构造函数逻辑15
//16
}17
[DllImport("advapi32.dll")]18
public static extern int LockServiceDatabase(int hSCManager);19
20
[DllImport("advapi32.dll")]21
public static extern bool UnlockServiceDatabase(int hSCManager);22
23
[DllImport("kernel32.dll")]24
public static extern void CopyMemory(IntPtr pDst, SC_ACTION[] pSrc,int ByteLen);25
26
[DllImport("advapi32.dll")]27
public static extern bool ChangeServiceConfigA(28
int hService, ServiceType dwServiceType, int dwStartType,29
int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup,30
int lpdwTagId, string lpDependencies, string lpServiceStartName,31
string lpPassword, string lpDisplayName);32
33
[DllImport("advapi32.dll")]34
public static extern bool ChangeServiceConfig2A(35
int hService, InfoLevel dwInfoLevel, 36
[MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);37

38
[DllImport("advapi32.dll")]39
public static extern bool ChangeServiceConfig2A(40
int hService, InfoLevel dwInfoLevel, 41
[MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo);42

43
[DllImport("advapi32.dll")]44
public static extern int OpenServiceA(45
int hSCManager, string lpServiceName, ACCESS_TYPE dwDesiredAccess);46

47
[DllImport("advapi32.dll")]48
public static extern int OpenSCManagerA(49
string lpMachineName, string lpDatabaseName, ServiceControlManagerType dwDesiredAccess);50

51
[DllImport("advapi32.dll")]52
public static extern bool CloseServiceHandle(53
int hSCObject);54

55
[DllImport("advapi32.dll")]56
public static extern bool QueryServiceConfigA(57
int hService, [MarshalAs(UnmanagedType.Struct)] ref QUERY_SERVICE_CONFIG lpServiceConfig, int cbBufSize,58
int pcbBytesNeeded);59
[DllImport("advapi32.dll")]60
public static extern int StartService(int SVHANDLE,int dwNumServiceArgs,string lpServiceArgVectors);61

62
public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;63
public const int GENERIC_READ = -2147483648;64
public const int ERROR_INSUFFICIENT_BUFFER = 122;65
public const int SERVICE_NO_CHANGE = -1;66
//public const int SERVICE_NO_CHANGE = 0xFFFF;67

68
public enum ServiceType69

{70
SERVICE_KERNEL_DRIVER = 0x1,71
SERVICE_FILE_SYSTEM_DRIVER = 0x2,72
SERVICE_WIN32_OWN_PROCESS = 0x10,73
SERVICE_WIN32_SHARE_PROCESS = 0x20,74
SERVICE_INTERACTIVE_PROCESS = 0x100,75
SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE76
}77

78
public enum ServiceStartType:int79

{80
SERVICE_BOOT_START = 0x0,81
SERVICE_SYSTEM_START = 0x1,82
SERVICE_AUTO_START = 0x2,83
SERVICE_DEMAND_START = 0x3,84
SERVICE_DISABLED = 0x4,85
SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE86
}87

88
public enum ServiceErrorControl:int89

{90
SERVICE_ERROR_IGNORE = 0x0,91
SERVICE_ERROR_NORMAL = 0x1,92
SERVICE_ERROR_SEVERE = 0x2,93
SERVICE_ERROR_CRITICAL = 0x3,94
msidbServiceInstallErrorControlVital = 0x8000,95
SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE96
}97

98
public enum ServiceStateRequest:int99

{100
SERVICE_ACTIVE = 0x1,101
SERVICE_INACTIVE = 0x2,102
SERVICE_STATE_ALL = (SERVICE_ACTIVE + SERVICE_INACTIVE)103
}104

105
public enum ServiceControlType:int106

{107
SERVICE_CONTROL_STOP = 0x1,108
SERVICE_CONTROL_PAUSE = 0x2,109
SERVICE_CONTROL_CONTINUE = 0x3,110
SERVICE_CONTROL_INTERROGATE = 0x4,111
SERVICE_CONTROL_SHUTDOWN = 0x5,112
SERVICE_CONTROL_PARAMCHANGE = 0x6,113
SERVICE_CONTROL_NETBINDADD = 0x7,114
SERVICE_CONTROL_NETBINDREMOVE = 0x8,115
SERVICE_CONTROL_NETBINDENABLE = 0x9,116
SERVICE_CONTROL_NETBINDDISABLE = 0xA,117
SERVICE_CONTROL_DEVICEEVENT = 0xB,118
SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC,119
SERVICE_CONTROL_POWEREVENT = 0xD,120
SERVICE_CONTROL_SESSIONCHANGE = 0xE,121
}122

123
public enum ServiceState:int124

{125
SERVICE_STOPPED = 0x1,126
SERVICE_START_PENDING = 0x2,127
SERVICE_STOP_PENDING = 0x3,128
SERVICE_RUNNING = 0x4,129
SERVICE_CONTINUE_PENDING = 0x5,130
SERVICE_PAUSE_PENDING = 0x6,131
SERVICE_PAUSED = 0x7,132
}133

134
public enum ServiceControlAccepted:int135

{136
SERVICE_ACCEPT_STOP = 0x1,137
SERVICE_ACCEPT_PAUSE_CONTINUE = 0x2,138
SERVICE_ACCEPT_SHUTDOWN = 0x4,139
SERVICE_ACCEPT_PARAMCHANGE = 0x8,140
SERVICE_ACCEPT_NETBINDCHANGE = 0x10,141
SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x20,142
SERVICE_ACCEPT_POWEREVENT = 0x40,143
SERVICE_ACCEPT_SESSIONCHANGE = 0x80144
}145

146
public enum ServiceControlManagerType:int147

{148
SC_MANAGER_CONNECT = 0x1,149
SC_MANAGER_CREATE_SERVICE = 0x2,150
SC_MANAGER_ENUMERATE_SERVICE = 0x4,151
SC_MANAGER_LOCK = 0x8,152
SC_MANAGER_QUERY_LOCK_STATUS = 0x10,153
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x20,154
SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SC_MANAGER_CONNECT + SC_MANAGER_CREATE_SERVICE + SC_MANAGER_ENUMERATE_SERVICE + SC_MANAGER_LOCK + SC_MANAGER_QUERY_LOCK_STATUS + SC_MANAGER_MODIFY_BOOT_CONFIG155
}156

157
public enum ACCESS_TYPE:int158

{159
SERVICE_QUERY_CONFIG = 0x1,160
SERVICE_CHANGE_CONFIG = 0x2,161
SERVICE_QUERY_STATUS = 0x4,162
SERVICE_ENUMERATE_DEPENDENTS = 0x8,163
SERVICE_START = 0x10,164
SERVICE_STOP = 0x20,165
SERVICE_PAUSE_CONTINUE = 0x40,166
SERVICE_INTERROGATE = 0x80,167
SERVICE_USER_DEFINED_CONTROL = 0x100,168
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_CONTROL169
}170

171
[StructLayout(LayoutKind.Sequential)]172
public struct SERVICE_STATUS173

{174
public int dwServiceType;175
public int dwCurrentState;176
public int dwControlsAccepted;177
public int dwWin32ExitCode;178
public int dwServiceSpecificExitCode;179
public int dwCheckPoint;180
public int dwWaitHint;181
}182
183
[StructLayout(LayoutKind.Sequential)]184
public struct QUERY_SERVICE_CONFIG185

{186
public int dwServiceType;187
public int dwStartType;188
public int dwErrorControl;189
public string lpBinaryPathName;190
public string lpLoadOrderGroup;191
public int dwTagId;192
public string lpDependencies;193
public string lpServiceStartName;194
public string lpDisplayName;195
}196

197
public enum SC_ACTION_TYPE:int198

{199
SC_ACTION_NONE = 0,200
SC_ACTION_RESTART = 1,201
SC_ACTION_REBOOT = 2,202
SC_ACTION_RUN_COMMAND = 3,203
}204

205
[StructLayout(LayoutKind.Sequential)]206
public struct SC_ACTION207

{208
public SC_ACTION_TYPE SCActionType;209
public int Delay;210
}211
public enum InfoLevel:int212

{213
SERVICE_CONFIG_DESCRIPTION = 1,214
SERVICE_CONFIG_FAILURE_ACTIONS = 2215
}216

217
[StructLayout(LayoutKind.Sequential)]218
public struct SERVICE_DESCRIPTION219

{220
public string lpDescription;221
}222

223
[StructLayout(LayoutKind.Sequential)]224
public struct SERVICE_FAILURE_ACTIONS225

{226
public int dwResetPeriod;227
public string lpRebootMsg;228
public string lpCommand;229
public int cActions;230
public int lpsaActions;231
}232
}233
}234

235

服务程序安装类 ProjectInstaller.cs
1
using System;2
using System.Collections;3
using System.ComponentModel;4
using System.Configuration.Install;5
using System.Runtime.InteropServices;6

7
namespace ScanSMSService8


{9

/**//// <summary>10
/// ProjectInstaller 的摘要说明。11
/// </summary>12
[RunInstaller(true)]13
public class ProjectInstaller : System.Configuration.Install.Installer14

{15
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;16
private System.ServiceProcess.ServiceInstaller ScanSMSServiceInstaller;17

/**//// <summary>18
/// 必需的设计器变量。19
/// </summary>20
private System.ComponentModel.Container components = null;21

22
public ProjectInstaller()23

{24
// 该调用是设计器所必需的。25
InitializeComponent();26
// TODO: 在 InitializeComponent 调用后添加任何初始化27
this.Committed+=new InstallEventHandler(ProjectInstaller_Committed);28
this.AfterInstall += new InstallEventHandler(ProjectInstaller_AfterInstall);29

30
}31

32

/**//// <summary> 33
/// 清理所有正在使用的资源。34
/// </summary>35
protected override void Dispose( bool disposing )36

{37
if( disposing )38

{39
if(components != null)40

{41
components.Dispose();42
}43
}44
base.Dispose( disposing );45
}46

47

48

组件设计器生成的代码#region 组件设计器生成的代码49

/**//// <summary>50
/// 设计器支持所需的方法 - 不要使用代码编辑器修改51
/// 此方法的内容。52
/// </summary>53
private void InitializeComponent()54

{55
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();56
this.ScanSMSServiceInstaller = new System.ServiceProcess.ServiceInstaller();57
// 58
// serviceProcessInstaller159
// 60
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;61
this.serviceProcessInstaller1.Password = null;62
this.serviceProcessInstaller1.Username = null;63
// 64
// ScanSMSServiceInstaller65
// 66
this.ScanSMSServiceInstaller.DisplayName = "短信扫描程序";67
this.ScanSMSServiceInstaller.ServiceName = "ScanSMSService";68
this.ScanSMSServiceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;69
// 70
// ProjectInstaller71
// 72

this.Installers.AddRange(new System.Configuration.Install.Installer[]
{73
this.serviceProcessInstaller1,74
this.ScanSMSServiceInstaller});75

76
}77
#endregion78

79

80
private void ProjectInstaller_AfterInstall(object sender,System.Configuration.Install.InstallEventArgs e)81

{82

83
int iSCManagerHandle = 0;84
int iSCManagerLockHandle = 0;85
int iServiceHandle = 0;86
bool bChangeServiceConfig = false;87
bool bChangeServiceConfig2 = false;88

89
modAPI.SERVICE_DESCRIPTION ServiceDescription;90
modAPI.SERVICE_FAILURE_ACTIONS ServiceFailureActions;91
modAPI.SC_ACTION[] ScActions = new modAPI.SC_ACTION[3];92

93
bool bCloseService = false;94
bool bUnlockSCManager = false;95
bool bCloseSCManager = false;96

97
IntPtr iScActionsPointer = new IntPtr();98

99
try100

{101
//打开服务控制台102
iSCManagerHandle = modAPI.OpenSCManagerA(null, null, modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS);103

104
if (iSCManagerHandle < 1)105

{106
throw new Exception("不能打开服务管理器.");107
}108

109
iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle);110

111
112
if (iSCManagerLockHandle < 1)113

{114
throw new Exception("不能锁定服务管理器.");115
}116

117
//根据服务名"ScanSMSService",获得句柄118
iServiceHandle = modAPI.OpenServiceA(iSCManagerHandle, "ScanSMSService",modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS);119
if (iServiceHandle < 1)120

{121
throw new Exception("不能打开服务进行修改.");122
}123
124
bChangeServiceConfig = modAPI.ChangeServiceConfigA(iServiceHandle,125
modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS | modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS,126
modAPI.SERVICE_NO_CHANGE, modAPI.SERVICE_NO_CHANGE, null, null,127
0, null, null, null, null);128

129
130
if (bChangeServiceConfig==false)131

{132
throw new Exception("不能改变服务设置.");133
}134
//短信扫描服务,如果停止该服务,短信将不能发送!135
ServiceDescription.lpDescription = "";136

137
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION,ref ServiceDescription);138

139
if (bChangeServiceConfig2==false)140

{141
throw new Exception("不能进行服务描述更改.");142
} 143

144
ServiceFailureActions.dwResetPeriod = 600;145
ServiceFailureActions.lpRebootMsg = "服务启动失败! 重启中
";146
// ServiceFailureActions.lpCommand = "SomeCommand.exe Param1 Param2";147
ServiceFailureActions.lpCommand = "";148
ServiceFailureActions.cActions = ScActions.Length;149

150
//故障恢复设置,这里没有设置151
ScActions[0].Delay = 20000;152
//不要对失败操作做任何处理,如重启服务等153
ScActions[0].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE; //什么都不做 154
ScActions[1].Delay = 20000;155
ScActions[1].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE;156
ScActions[2].Delay = 20000;157
ScActions[2].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE; 158

159
iScActionsPointer = Marshal.AllocHGlobal(Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);160

161
modAPI.CopyMemory(iScActionsPointer, ScActions, Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);162
ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32();163

164
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,165
modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS,ref ServiceFailureActions);166

167
if (bChangeServiceConfig2==false)168

{169
throw new Exception("不能设置服务的故障恢复设置.");170
}171

172
}173
catch(Exception ex)174

{175
throw new Exception(ex.Message);176
}177
finally178

{179
180
Marshal.FreeHGlobal(iScActionsPointer);181
if (iServiceHandle > 0)182

{183
bCloseService = modAPI.CloseServiceHandle(iServiceHandle);184
}185
if (iSCManagerLockHandle > 0)186

{187
bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle);188
}189
if (iSCManagerHandle != 0)190

{191
bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle);192
}193
}194
}195
private void ProjectInstaller_Committed(object sender, InstallEventArgs e)196

{197
//Do Nothing
198
}199
}200
}201

参考文章:http://doc.chinahtml.com/Manual/asp.net/dot42.htm
http://www.xker.com/Html/windows/2006_04_12_10_568.html
浙公网安备 33010602011771号