设置程序在Windows开机后自动运行的方式
设置程序开机自动运行的方式主要有三种:
一、把快捷方式复制到[开始->所有程序->启动]中。
二、程序添加到Windows开机选项中启动运行。
三.程序以Windows Service的方式启动。
设置程序开机自动运行的方式主要有三种:
一、把快捷方式复制到[开始->所有程序->启动]中。这个得依赖用户的操作。
二、程序添加到Windows开机选项中启动运行。
把程序启动路径写进注册表中,如把程序“C:\a.exe”存放到下列注册表项中:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run或
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
新建注册表项的时候要注意一个问题,如果程序路径包含空格,比如C:\Program Files\ddd dd\a.exe,
设置注册表value值时,需要添加双引号,如“C:\Program Files\ddd dd\a.exe”
采用上述两种方式启动程序有一个缺点:必须在用户login之后,程序才会随之启动。要使得程序开机后没有
用户login之前启动运行,可以采用下一种方式。
三.程序以Windows Service的方式启动。
在.NET中,可以方便的把一个程序指定以Windows Service方式启动,具体显现过程如下:
1.打开Visual Studio,创建一个Windows Application 项目。
2.在创建好的项目中添加一个New Item,在Item的选项中可以看到一个Windows Service的Item,
如下图所示:
3.在新创建的Service1.cs的代码文件中,可以看到OnStart()、OnStop()方法。
protected override void OnStart(string[] args) { //添加启动服务时,调用的方法 } protected override void OnStop() { //添加停止服务时,进行的必要操作 }
4. 在program.cs中,添加必要的启动服务的代码。
class Program { static void Main(string[] args) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } }
5.接下来,需要添加一个服务的安装程序。打开Service1.cs的Designer视图,点击鼠标右键,可以看到“Add Installer”的选项,选中该选项。
默认会多出来一个ProjectInstaller.cs文件。
6.打开新创建的ProjectInstaller.cs文件的Designer视图,可以看到serviceInstaller1和serviceProcessInstaller1两个组件。
分别查看这两个组件的属性,可以看到:
serviceInstaller1:设置ServiceName,如Service1;设置StartType,如Automatic。
serviceProcessInstaller1:设置Account,如LocalSystem(这样就不用用户登录,也能启动服务了)。
7.设置完上述选项,还需要创建一个Project的部署程序,这样才能把配置好的程序部署到Windows Service中。
在Visual Studio中,选中Other Project Type,创建一个Setup and Deployment工程。
8.在创建好的setup工程中,添加一个Project Output,把上述service1所在的项目添加为Primary Output。
9.鼠标右键点击setup工程,选择View/Custom Actions,然后选中Custom Actions添加一个新的Primary Output,
双击Application Folder,可以看到8中创建的Primary Output,添加进来。
通过上述过程,编译setup项目,就可以点击安装了,安装完在Windows Service中可以看到一个新的Service选项。
但是这样还是有问题的,因为多次安装会发现安装服务时出错,会提示“服务已经存在,无法安装”、“Windows Service: Specified Service Already Exists”之类的错误。
如果要在一个机器上多次部署同一个Windows Service。在上述5中的ProjectInstaller.cs文件中,要做一些相应的更改。
安装前需要进行检查,如果服务已经安装,可以先卸载掉已经安装的服务,然后再进行后面的安装。
卸载一个Windows Service的方法,可以重载ProjectInstaller.cs中的OnBeforeInstall方法。
protected override void OnBeforeInstall(IDictionary savedState) { base.OnBeforeInstall(savedState); ServiceInstaller.Uninstall(SERVICE_NAME); }
上述的ServiceInstaller类实现如下:
2 {
3 privateconstint STANDARD_RIGHTS_REQUIRED =0xF0000;
4 privateconstint SERVICE_WIN32_OWN_PROCESS =0x00000010;
5
6 [StructLayout(LayoutKind.Sequential)]
7 privateclass SERVICE_STATUS
8 {
9 publicint dwServiceType =0;
10 public ServiceState dwCurrentState =0;
11 publicint dwControlsAccepted =0;
12 publicint dwWin32ExitCode =0;
13 publicint dwServiceSpecificExitCode =0;
14 publicint dwCheckPoint =0;
15 publicint dwWaitHint =0;
16 }
17
18 #region OpenSCManager
19 [DllImport(“advapi32.dll“, EntryPoint =“OpenSCManagerW“, ExactSpelling =true, CharSet = CharSet.Unicode, SetLastError =true)]
20 staticextern IntPtr OpenSCManager(string machineName, string databaseName, ScmAccessRights dwDesiredAccess);
21 #endregion
22
23 #region OpenService
24 [DllImport(“advapi32.dll“, SetLastError =true, CharSet = CharSet.Auto)]
25 staticextern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceAccessRights dwDesiredAccess);
26 #endregion
27
28 #region CreateService
29 [DllImport(“advapi32.dll“, SetLastError =true, CharSet = CharSet.Auto)]
30 privatestaticextern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceAccessRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword);
31 #endregion
32
33 #region CloseServiceHandle
34 [DllImport(“advapi32.dll“, SetLastError =true)]
35 [return: MarshalAs(UnmanagedType.Bool)]
36 staticexternbool CloseServiceHandle(IntPtr hSCObject);
37 #endregion
38
39 #region QueryServiceStatus
40 [DllImport(“advapi32.dll“)]
41 privatestaticexternint QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus);
42 #endregion
43
44 #region DeleteService
45 [DllImport(“advapi32.dll“, SetLastError =true)]
46 [return: MarshalAs(UnmanagedType.Bool)]
47 privatestaticexternbool DeleteService(IntPtr hService);
48 #endregion
49
50 #region ControlService
51 [DllImport(“advapi32.dll“)]
52 privatestaticexternint ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus);
53 #endregion
54
55 #region StartService
56 [DllImport(“advapi32.dll“, SetLastError =true)]
57 privatestaticexternint StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors);
58 #endregion
59
60 publicstaticvoid Uninstall(string serviceName)
61 {
62 IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);
63
64 try
65 {
66 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);
67 if (service == IntPtr.Zero)
68 {
69 return;
70 }
71
72 try
73 {
74 StopService(service);
75 if (!DeleteService(service))
76 thrownew ApplicationException(“Could not delete service “+ Marshal.GetLastWin32Error());
77 }
78 finally
79 {
80 CloseServiceHandle(service);
81 }
82 }
83 finally
84 {
85 CloseServiceHandle(scm);
86 }
87 }
88
89 publicstaticbool ServiceIsInstalled(string serviceName)
90 {
91 IntPtr scm = OpenSCManager(ScmAccessRights.Connect);
92
93 try
94 {
95 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);
96
97 if (service == IntPtr.Zero)
98 returnfalse;
99
100 CloseServiceHandle(service);
101 returntrue;
102 }
103 finally
104 {
105 CloseServiceHandle(scm);
106 }
107 }
108
109 publicstaticvoid InstallAndStart(string serviceName, string displayName, string fileName)
110 {
111 IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);
112
113 try
114 {
115 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);
116
117 if (service == IntPtr.Zero)
118 service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, ServiceBootFlag.AutoStart, ServiceError.Normal, fileName, null, IntPtr.Zero, null, null, null);
119
120 if (service == IntPtr.Zero)
121 thrownew ApplicationException(“Failed to install service.“);
122
123 try
124 {
125 StartService(service);
126 }
127 finally
128 {
129 CloseServiceHandle(service);
130 }
131 }
132 finally
133 {
134 CloseServiceHandle(scm);
135 }
136 }
137
138 publicstaticvoid StartService(string serviceName)
139 {
140 IntPtr scm = OpenSCManager(ScmAccessRights.Connect);
141
142 try
143 {
144 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Start);
145 if (service == IntPtr.Zero)
146 thrownew ApplicationException(“Could not open service.“);
147
148 try
149 {
150 StartService(service);
151 }
152 finally
153 {
154 CloseServiceHandle(service);
155 }
156 }
157 finally
158 {
159 CloseServiceHandle(scm);
160 }
161 }
162
163 publicstaticvoid StopService(string serviceName)
164 {
165 IntPtr scm = OpenSCManager(ScmAccessRights.Connect);
166
167 try
168 {
169 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Stop);
170 if (service == IntPtr.Zero)
171 thrownew ApplicationException(“Could not open service.“);
172
173 try
174 {
175 StopService(service);
176 }
177 finally
178 {
179 CloseServiceHandle(service);
180 }
181 }
182 finally
183 {
184 CloseServiceHandle(scm);
185 }
186 }
187
188 privatestaticvoid StartService(IntPtr service)
189 {
190 SERVICE_STATUS status =new SERVICE_STATUS();
191 StartService(service, 0, 0);
192 var changedStatus = WaitForServiceStatus(service, ServiceState.StartPending, ServiceState.Running);
193 if (!changedStatus)
194 thrownew ApplicationException(“Unable to start service“);
195 }
196
197 privatestaticvoid StopService(IntPtr service)
198 {
199 SERVICE_STATUS status =new SERVICE_STATUS();
200 ControlService(service, ServiceControl.Stop, status);
201 var changedStatus = WaitForServiceStatus(service, ServiceState.StopPending, ServiceState.Stopped);
202 if (!changedStatus)
203 thrownew ApplicationException(“Unable to stop service“);
204 }
205
206 publicstatic ServiceState GetServiceStatus(string serviceName)
207 {
208 IntPtr scm = OpenSCManager(ScmAccessRights.Connect);
209
210 try
211 {
212 IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);
213 if (service == IntPtr.Zero)
214 return ServiceState.NotFound;
215
216 try
217 {
218 return GetServiceStatus(service);
219 }
220 finally
221 {
222 CloseServiceHandle(service);
223 }
224 }
225 finally
226 {
227 CloseServiceHandle(scm);
228 }
229 }
230
231 privatestatic ServiceState GetServiceStatus(IntPtr service)
232 {
233 SERVICE_STATUS status =new SERVICE_STATUS();
234
235 if (QueryServiceStatus(service, status) ==0)
236 thrownew ApplicationException(“Failed to query service status.“);
237
238 return status.dwCurrentState;
239 }
240
241 privatestaticbool WaitForServiceStatus(IntPtr service, ServiceState waitStatus, ServiceState desiredStatus)
242 {
243 SERVICE_STATUS status =new SERVICE_STATUS();
244
245 QueryServiceStatus(service, status);
246 if (status.dwCurrentState == desiredStatus) returntrue;
247
248 int dwStartTickCount = Environment.TickCount;
249 int dwOldCheckPoint = status.dwCheckPoint;
250
251 while (status.dwCurrentState == waitStatus)
252 {
253 // Do not wait longer than the wait hint. A good interval is
254 // one tenth the wait hint, but no less than 1 second and no
255 // more than 10 seconds.
256
257 int dwWaitTime = status.dwWaitHint /10;
258
259 if (dwWaitTime <1000) dwWaitTime =1000;
260 elseif (dwWaitTime >10000) dwWaitTime =10000;
261
262 Thread.Sleep(dwWaitTime);
263
264 // Check the status again.
265
266 if (QueryServiceStatus(service, status) ==0) break;
267
268 if (status.dwCheckPoint > dwOldCheckPoint)
269 {
270 // The service is making progress.
271 dwStartTickCount = Environment.TickCount;
272 dwOldCheckPoint = status.dwCheckPoint;
273 }
274 else
275 {
276 if (Environment.TickCount – dwStartTickCount > status.dwWaitHint)
277 {
278 // No progress made within the wait hint
279 break;
280 }
281 }
282 }
283 return (status.dwCurrentState == desiredStatus);
284 }
285
286 privatestatic IntPtr OpenSCManager(ScmAccessRights rights)
287 {
288 IntPtr scm = OpenSCManager(null, null, rights);
289 if (scm == IntPtr.Zero)
290 thrownew ApplicationException(“Could not connect to service control manager.“);
291
292 return scm;
293 }
294 }
295
296
297 publicenum ServiceState
298 {
299 Unknown =–1, // The state cannot be (has not been) retrieved.
300 NotFound =0, // The service is not known on the host server.
301 Stopped =1,
302 StartPending =2,
303 StopPending =3,
304 Running =4,
305 ContinuePending =5,
306 PausePending =6,
307 Paused =7
308 }
309
310 [Flags]
311 publicenum ScmAccessRights
312 {
313 Connect =0x0001,
314 CreateService =0x0002,
315 EnumerateService =0x0004,
316 Lock =0x0008,
317 QueryLockStatus =0x0010,
318 ModifyBootConfig =0x0020,
319 StandardRightsRequired =0xF0000,
320 AllAccess = (StandardRightsRequired | Connect | CreateService |
321 EnumerateService | Lock | QueryLockStatus | ModifyBootConfig)
322 }
323
324 [Flags]
325 publicenum ServiceAccessRights
326 {
327 QueryConfig =0x1,
328 ChangeConfig =0x2,
329 QueryStatus =0x4,
330 EnumerateDependants =0x8,
331 Start =0x10,
332 Stop =0x20,
333 PauseContinue =0x40,
334 Interrogate =0x80,
335 UserDefinedControl =0x100,
336 Delete =0x00010000,
337 StandardRightsRequired =0xF0000,
338 AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig |
339 QueryStatus | EnumerateDependants | Start | Stop | PauseContinue |
340 Interrogate | UserDefinedControl)
341 }
342
343 publicenum ServiceBootFlag
344 {
345 Start =0x00000000,
346 SystemStart =0x00000001,
347 AutoStart =0x00000002,
348 DemandStart =0x00000003,
349 Disabled =0x00000004
350 }
351
352 publicenum ServiceControl
353 {
354 Stop =0x00000001,
355 Pause =0x00000002,
356 Continue =0x00000003,
357 Interrogate =0x00000004,
358 Shutdown =0x00000005,
359 ParamChange =0x00000006,
360 NetBindAdd =0x00000007,
361 NetBindRemove =0x00000008,
362 NetBindEnable =0x00000009,
363 NetBindDisable =0x0000000A
364 }
365
366 publicenum ServiceError
367 {
368 Ignore =0x00000000,
369 Normal =0x00000001,
370 Severe =0x00000002,
371 Critical =0x00000003
372 }