设置程序在Windows开机后自动运行的方式

设置程序开机自动运行的方式主要有三种:

一、把快捷方式复制到[开始->所有程序->启动]中。这个得依赖用户的操作。

二、程序添加到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类实现如下:

 

代码
1 public static class ServiceInstaller
2 {
3 private const int STANDARD_RIGHTS_REQUIRED = 0xF0000 ;
4 private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010 ;
5
6 [StructLayout(LayoutKind.Sequential)]
7 private class SERVICE_STATUS
8 {
9 public int dwServiceType = 0 ;
10 public ServiceState dwCurrentState = 0 ;
11 public int dwControlsAccepted = 0 ;
12 public int dwWin32ExitCode = 0 ;
13 public int dwServiceSpecificExitCode = 0 ;
14 public int dwCheckPoint = 0 ;
15 public int dwWaitHint = 0 ;
16 }
17
18 #region OpenSCManager
19 [DllImport( " advapi32.dll " , EntryPoint = " OpenSCManagerW " , ExactSpelling = true , CharSet = CharSet.Unicode, SetLastError = true )]
20 static extern IntPtr OpenSCManager( string machineName, string databaseName, ScmAccessRights dwDesiredAccess);
21 #endregion
22
23 #region OpenService
24 [DllImport( " advapi32.dll " , SetLastError = true , CharSet = CharSet.Auto)]
25 static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceAccessRights dwDesiredAccess);
26 #endregion
27
28 #region CreateService
29 [DllImport( " advapi32.dll " , SetLastError = true , CharSet = CharSet.Auto)]
30 private static extern 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 static extern bool CloseServiceHandle(IntPtr hSCObject);
37 #endregion
38
39 #region QueryServiceStatus
40 [DllImport( " advapi32.dll " )]
41 private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus);
42 #endregion
43
44 #region DeleteService
45 [DllImport( " advapi32.dll " , SetLastError = true )]
46 [ return : MarshalAs(UnmanagedType.Bool)]
47 private static extern bool DeleteService(IntPtr hService);
48 #endregion
49
50 #region ControlService
51 [DllImport( " advapi32.dll " )]
52 private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus);
53 #endregion
54
55 #region StartService
56 [DllImport( " advapi32.dll " , SetLastError = true )]
57 private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors);
58 #endregion
59
60 public static void 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 throw new 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 public static bool 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 return false ;
99
100 CloseServiceHandle(service);
101 return true ;
102 }
103 finally
104 {
105 CloseServiceHandle(scm);
106 }
107 }
108
109 public static void 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 throw new 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 public static void 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 throw new 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 public static void 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 throw new 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 private static void 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 throw new ApplicationException( " Unable to start service " );
195 }
196
197 private static void 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 throw new ApplicationException( " Unable to stop service " );
204 }
205
206 public static 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 private static ServiceState GetServiceStatus(IntPtr service)
232 {
233 SERVICE_STATUS status = new SERVICE_STATUS();
234
235 if (QueryServiceStatus(service, status) == 0 )
236 throw new ApplicationException( " Failed to query service status. " );
237
238 return status.dwCurrentState;
239 }
240
241 private static bool 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) return true ;
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 else if (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 private static IntPtr OpenSCManager(ScmAccessRights rights)
287 {
288 IntPtr scm = OpenSCManager( null , null , rights);
289 if (scm == IntPtr.Zero)
290 throw new ApplicationException( " Could not connect to service control manager. " );
291
292 return scm;
293 }
294 }
295
296
297 public enum 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 public enum 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 public enum 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 public enum ServiceBootFlag
344 {
345 Start = 0x00000000 ,
346 SystemStart = 0x00000001 ,
347 AutoStart = 0x00000002 ,
348 DemandStart = 0x00000003 ,
349 Disabled = 0x00000004
350 }
351
352 public enum 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 public enum ServiceError
367 {
368 Ignore = 0x00000000 ,
369 Normal = 0x00000001 ,
370 Severe = 0x00000002 ,
371 Critical = 0x00000003
372 }

 

转载于:https://www.cnblogs.com/ahomer/archive/2010/11/11/1875017.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值