Cukor

Untitled

Jun 4th, 2014
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.96 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5.  
  6. namespace ServiceTools
  7. {
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. [Flags]
  12. public enum ServiceManagerRights
  13. {
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. Connect = 0x0001,
  18. /// <summary>
  19. ///
  20. /// </summary>
  21. CreateService = 0x0002,
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. EnumerateService = 0x0004,
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. Lock = 0x0008,
  30. /// <summary>
  31. ///
  32. /// </summary>
  33. QueryLockStatus = 0x0010,
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. ModifyBootConfig = 0x0020,
  38. /// <summary>
  39. ///
  40. /// </summary>
  41. StandardRightsRequired = 0xF0000,
  42. /// <summary>
  43. ///
  44. /// </summary>
  45. AllAccess = (StandardRightsRequired | Connect | CreateService |
  46. EnumerateService | Lock | QueryLockStatus | ModifyBootConfig)
  47. }
  48.  
  49. /// <summary>
  50. ///
  51. /// </summary>
  52. [Flags]
  53. public enum ServiceRights
  54. {
  55. /// <summary>
  56. ///
  57. /// </summary>
  58. QueryConfig = 0x1,
  59. /// <summary>
  60. ///
  61. /// </summary>
  62. ChangeConfig = 0x2,
  63. /// <summary>
  64. ///
  65. /// </summary>
  66. QueryStatus = 0x4,
  67. /// <summary>
  68. ///
  69. /// </summary>
  70. EnumerateDependants = 0x8,
  71. /// <summary>
  72. ///
  73. /// </summary>
  74. Start = 0x10,
  75. /// <summary>
  76. ///
  77. /// </summary>
  78. Stop = 0x20,
  79. /// <summary>
  80. ///
  81. /// </summary>
  82. PauseContinue = 0x40,
  83. /// <summary>
  84. ///
  85. /// </summary>
  86. Interrogate = 0x80,
  87. /// <summary>
  88. ///
  89. /// </summary>
  90. UserDefinedControl = 0x100,
  91. /// <summary>
  92. ///
  93. /// </summary>
  94. Delete = 0x00010000,
  95. /// <summary>
  96. ///
  97. /// </summary>
  98. StandardRightsRequired = 0xF0000,
  99. /// <summary>
  100. ///
  101. /// </summary>
  102. AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig |
  103. QueryStatus | EnumerateDependants | Start | Stop | PauseContinue |
  104. Interrogate | UserDefinedControl)
  105. }
  106.  
  107. /// <summary>
  108. ///
  109. /// </summary>
  110. public enum ServiceBootFlag
  111. {
  112. /// <summary>
  113. ///
  114. /// </summary>
  115. Start = 0x00000000,
  116. /// <summary>
  117. ///
  118. /// </summary>
  119. SystemStart = 0x00000001,
  120. /// <summary>
  121. ///
  122. /// </summary>
  123. AutoStart = 0x00000002,
  124. /// <summary>
  125. ///
  126. /// </summary>
  127. DemandStart = 0x00000003,
  128. /// <summary>
  129. ///
  130. /// </summary>
  131. Disabled = 0x00000004
  132. }
  133.  
  134. /// <summary>
  135. ///
  136. /// </summary>
  137. public enum ServiceState
  138. {
  139. /// <summary>
  140. ///
  141. /// </summary>
  142. Unknown = -1, // The state cannot be (has not been) retrieved.
  143. /// <summary>
  144. ///
  145. /// </summary>
  146. NotFound = 0, // The service is not known on the host server.
  147. /// <summary>
  148. ///
  149. /// </summary>
  150. Stop = 1, // The service is NET stopped.
  151. /// <summary>
  152. ///
  153. /// </summary>
  154. Run = 2, // The service is NET started.
  155. /// <summary>
  156. ///
  157. /// </summary>
  158. Stopping = 3,
  159. /// <summary>
  160. ///
  161. /// </summary>
  162. Starting = 4,
  163. }
  164.  
  165. /// <summary>
  166. ///
  167. /// </summary>
  168. public enum ServiceControl
  169. {
  170. /// <summary>
  171. ///
  172. /// </summary>
  173. Stop = 0x00000001,
  174. /// <summary>
  175. ///
  176. /// </summary>
  177. Pause = 0x00000002,
  178. /// <summary>
  179. ///
  180. /// </summary>
  181. Continue = 0x00000003,
  182. /// <summary>
  183. ///
  184. /// </summary>
  185. Interrogate = 0x00000004,
  186. /// <summary>
  187. ///
  188. /// </summary>
  189. Shutdown = 0x00000005,
  190. /// <summary>
  191. ///
  192. /// </summary>
  193. ParamChange = 0x00000006,
  194. /// <summary>
  195. ///
  196. /// </summary>
  197. NetBindAdd = 0x00000007,
  198. /// <summary>
  199. ///
  200. /// </summary>
  201. NetBindRemove = 0x00000008,
  202. /// <summary>
  203. ///
  204. /// </summary>
  205. NetBindEnable = 0x00000009,
  206. /// <summary>
  207. ///
  208. /// </summary>
  209. NetBindDisable = 0x0000000A
  210. }
  211.  
  212. /// <summary>
  213. ///
  214. /// </summary>
  215. public enum ServiceError
  216. {
  217. /// <summary>
  218. ///
  219. /// </summary>
  220. Ignore = 0x00000000,
  221. /// <summary>
  222. ///
  223. /// </summary>
  224. Normal = 0x00000001,
  225. /// <summary>
  226. ///
  227. /// </summary>
  228. Severe = 0x00000002,
  229. /// <summary>
  230. ///
  231. /// </summary>
  232. Critical = 0x00000003
  233. }
  234.  
  235. /// <summary>
  236. /// Installs and provides functionality for handling windows services
  237. /// </summary>
  238. public class ServiceInstaller
  239. {
  240. private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
  241. private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
  242.  
  243. [StructLayout(LayoutKind.Sequential)]
  244. private class SERVICE_STATUS
  245. {
  246. public int dwServiceType = 0;
  247. public ServiceState dwCurrentState = 0;
  248. public int dwControlsAccepted = 0;
  249. public int dwWin32ExitCode = 0;
  250. public int dwServiceSpecificExitCode = 0;
  251. public int dwCheckPoint = 0;
  252. public int dwWaitHint = 0;
  253. }
  254.  
  255. [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerA")]
  256. private static extern IntPtr OpenSCManager(string lpMachineName, string
  257. lpDatabaseName, ServiceManagerRights dwDesiredAccess);
  258. [DllImport("advapi32.dll", EntryPoint = "OpenServiceA",
  259. CharSet = CharSet.Ansi)]
  260. private static extern IntPtr OpenService(IntPtr hSCManager, string
  261. lpServiceName, ServiceRights dwDesiredAccess);
  262. [DllImport("advapi32.dll", EntryPoint = "CreateServiceA")]
  263. private static extern IntPtr CreateService(IntPtr hSCManager, string
  264. lpServiceName, string lpDisplayName, ServiceRights dwDesiredAccess, int
  265. dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl,
  266. string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string
  267. lpDependencies, string lp, string lpPassword);
  268. [DllImport("advapi32.dll")]
  269. private static extern int CloseServiceHandle(IntPtr hSCObject);
  270. [DllImport("advapi32.dll")]
  271. private static extern int QueryServiceStatus(IntPtr hService,
  272. SERVICE_STATUS lpServiceStatus);
  273. [DllImport("advapi32.dll", SetLastError = true)]
  274. private static extern int DeleteService(IntPtr hService);
  275. [DllImport("advapi32.dll")]
  276. private static extern int ControlService(IntPtr hService, ServiceControl
  277. dwControl, SERVICE_STATUS lpServiceStatus);
  278. [DllImport("advapi32.dll", EntryPoint = "StartServiceA")]
  279. private static extern int StartService(IntPtr hService, int
  280. dwNumServiceArgs, int lpServiceArgVectors);
  281.  
  282. /// <summary>
  283. ///
  284. /// </summary>
  285. public ServiceInstaller()
  286. {
  287. }
  288.  
  289. /// <summary>
  290. /// Takes a service name and tries to stop and then uninstall the windows serviceError
  291. /// </summary>
  292. /// <param name="ServiceName">The windows service name to uninstall</param>
  293. public static void Uninstall(string ServiceName)
  294. {
  295. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
  296. try
  297. {
  298. IntPtr service = OpenService(scman, ServiceName,
  299. ServiceRights.StandardRightsRequired | ServiceRights.Stop |
  300. ServiceRights.QueryStatus);
  301. if (service == IntPtr.Zero)
  302. {
  303. throw new ApplicationException("Service not installed.");
  304. }
  305. try
  306. {
  307. StopService(service);
  308. int ret = DeleteService(service);
  309. if (ret == 0)
  310. {
  311. int error = Marshal.GetLastWin32Error();
  312. throw new ApplicationException("Could not delete service " + error);
  313. }
  314. }
  315. finally
  316. {
  317. CloseServiceHandle(service);
  318. }
  319. }
  320. finally
  321. {
  322. CloseServiceHandle(scman);
  323. }
  324. }
  325.  
  326. /// <summary>
  327. /// Accepts a service name and returns true if the service with that service name exists
  328. /// </summary>
  329. /// <param name="ServiceName">The service name that we will check for existence</param>
  330. /// <returns>True if that service exists false otherwise</returns>
  331. public static bool ServiceIsInstalled(string ServiceName)
  332. {
  333. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
  334. try
  335. {
  336. IntPtr service = OpenService(scman, ServiceName,
  337. ServiceRights.QueryStatus);
  338. if (service == IntPtr.Zero) return false;
  339. CloseServiceHandle(service);
  340. return true;
  341. }
  342. finally
  343. {
  344. CloseServiceHandle(scman);
  345. }
  346. }
  347.  
  348. /// <summary>
  349. /// Takes a service name, a service display name and the path to the service executable and installs / starts the windows service.
  350. /// </summary>
  351. /// <param name="ServiceName">The service name that this service will have</param>
  352. /// <param name="DisplayName">The display name that this service will have</param>
  353. /// <param name="FileName">The path to the executable of the service</param>
  354. public static void InstallAndStart(string ServiceName, string DisplayName,
  355. string FileName)
  356. {
  357. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect |
  358. ServiceManagerRights.CreateService);
  359. try
  360. {
  361. IntPtr service = OpenService(scman, ServiceName,
  362. ServiceRights.QueryStatus | ServiceRights.Start);
  363. if (service == IntPtr.Zero)
  364. {
  365. service = CreateService(scman, ServiceName, DisplayName,
  366. ServiceRights.QueryStatus | ServiceRights.Start, SERVICE_WIN32_OWN_PROCESS,
  367. ServiceBootFlag.AutoStart, ServiceError.Normal, FileName, null, IntPtr.Zero,
  368. null, null, null);
  369. }
  370. if (service == IntPtr.Zero)
  371. {
  372. throw new ApplicationException("Failed to install service.");
  373. }
  374. try
  375. {
  376. StartService(service);
  377. }
  378. finally
  379. {
  380. CloseServiceHandle(service);
  381. }
  382. }
  383. finally
  384. {
  385. CloseServiceHandle(scman);
  386. }
  387. }
  388.  
  389. /// <summary>
  390. /// Takes a service name and starts it
  391. /// </summary>
  392. /// <param name="Name">The service name</param>
  393. public static void StartService(string Name)
  394. {
  395. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
  396. try
  397. {
  398. IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus |
  399. ServiceRights.Start);
  400. if (hService == IntPtr.Zero)
  401. {
  402. throw new ApplicationException("Could not open service.");
  403. }
  404. try
  405. {
  406. StartService(hService);
  407. }
  408. finally
  409. {
  410. CloseServiceHandle(hService);
  411. }
  412. }
  413. finally
  414. {
  415. CloseServiceHandle(scman);
  416. }
  417. }
  418.  
  419. /// <summary>
  420. /// Stops the provided windows service
  421. /// </summary>
  422. /// <param name="Name">The service name that will be stopped</param>
  423. public static void StopService(string Name)
  424. {
  425. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
  426. try
  427. {
  428. IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus |
  429. ServiceRights.Stop);
  430. if (hService == IntPtr.Zero)
  431. {
  432. throw new ApplicationException("Could not open service.");
  433. }
  434. try
  435. {
  436. StopService(hService);
  437. }
  438. finally
  439. {
  440. CloseServiceHandle(hService);
  441. }
  442. }
  443. finally
  444. {
  445. CloseServiceHandle(scman);
  446. }
  447. }
  448.  
  449. /// <summary>
  450. /// Stars the provided windows service
  451. /// </summary>
  452. /// <param name="hService">The handle to the windows service</param>
  453. private static void StartService(IntPtr hService)
  454. {
  455. SERVICE_STATUS status = new SERVICE_STATUS();
  456. StartService(hService, 0, 0);
  457. WaitForServiceStatus(hService, ServiceState.Starting, ServiceState.Run);
  458. }
  459.  
  460. /// <summary>
  461. /// Stops the provided windows service
  462. /// </summary>
  463. /// <param name="hService">The handle to the windows service</param>
  464. private static void StopService(IntPtr hService)
  465. {
  466. SERVICE_STATUS status = new SERVICE_STATUS();
  467. ControlService(hService, ServiceControl.Stop, status);
  468. WaitForServiceStatus(hService, ServiceState.Stopping, ServiceState.Stop);
  469. }
  470.  
  471. /// <summary>
  472. /// Takes a service name and returns the <code>ServiceState</code> of the corresponding service
  473. /// </summary>
  474. /// <param name="ServiceName">The service name that we will check for his <code>ServiceState</code></param>
  475. /// <returns>The ServiceState of the service we wanted to check</returns>
  476. public static ServiceState GetServiceStatus(string ServiceName)
  477. {
  478. IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
  479. try
  480. {
  481. IntPtr hService = OpenService(scman, ServiceName,
  482. ServiceRights.QueryStatus);
  483. if (hService == IntPtr.Zero)
  484. {
  485. return ServiceState.NotFound;
  486. }
  487. try
  488. {
  489. return GetServiceStatus(hService);
  490. }
  491. finally
  492. {
  493. CloseServiceHandle(scman);
  494. }
  495. }
  496. finally
  497. {
  498. CloseServiceHandle(scman);
  499. }
  500. }
  501.  
  502. /// <summary>
  503. /// Gets the service state by using the handle of the provided windows service
  504. /// </summary>
  505. /// <param name="hService">The handle to the service</param>
  506. /// <returns>The <code>ServiceState</code> of the service</returns>
  507. private static ServiceState GetServiceStatus(IntPtr hService)
  508. {
  509. SERVICE_STATUS ssStatus = new SERVICE_STATUS();
  510. if (QueryServiceStatus(hService, ssStatus) == 0)
  511. {
  512. throw new ApplicationException("Failed to query service status.");
  513. }
  514. return ssStatus.dwCurrentState;
  515. }
  516.  
  517. /// <summary>
  518. /// Returns true when the service status has been changes from wait status to desired status
  519. /// ,this method waits around 10 seconds for this operation.
  520. /// </summary>
  521. /// <param name="hService">The handle to the service</param>
  522. /// <param name="WaitStatus">The current state of the service</param>
  523. /// <param name="DesiredStatus">The desired state of the service</param>
  524. /// <returns>bool if the service has successfully changed states within the allowed timeline</returns>
  525. private static bool WaitForServiceStatus(IntPtr hService, ServiceState
  526. WaitStatus, ServiceState DesiredStatus)
  527. {
  528. SERVICE_STATUS ssStatus = new SERVICE_STATUS();
  529. int dwOldCheckPoint;
  530. int dwStartTickCount;
  531.  
  532. QueryServiceStatus(hService, ssStatus);
  533. if (ssStatus.dwCurrentState == DesiredStatus) return true;
  534. dwStartTickCount = Environment.TickCount;
  535. dwOldCheckPoint = ssStatus.dwCheckPoint;
  536.  
  537. while (ssStatus.dwCurrentState == WaitStatus)
  538. {
  539. // Do not wait longer than the wait hint. A good interval is
  540. // one tenth the wait hint, but no less than 1 second and no
  541. // more than 10 seconds.
  542.  
  543. int dwWaitTime = ssStatus.dwWaitHint / 10;
  544.  
  545. if (dwWaitTime < 1000) dwWaitTime = 1000;
  546. else if (dwWaitTime > 10000) dwWaitTime = 10000;
  547.  
  548. System.Threading.Thread.Sleep(dwWaitTime);
  549.  
  550. // Check the status again.
  551.  
  552. if (QueryServiceStatus(hService, ssStatus) == 0) break;
  553.  
  554. if (ssStatus.dwCheckPoint > dwOldCheckPoint)
  555. {
  556. // The service is making progress.
  557. dwStartTickCount = Environment.TickCount;
  558. dwOldCheckPoint = ssStatus.dwCheckPoint;
  559. }
  560. else
  561. {
  562. if (Environment.TickCount - dwStartTickCount > ssStatus.dwWaitHint)
  563. {
  564. // No progress made within the wait hint
  565. break;
  566. }
  567. }
  568. }
  569. return (ssStatus.dwCurrentState == DesiredStatus);
  570. }
  571.  
  572. /// <summary>
  573. /// Opens the service manager
  574. /// </summary>
  575. /// <param name="Rights">The service manager rights</param>
  576. /// <returns>the handle to the service manager</returns>
  577. private static IntPtr OpenSCManager(ServiceManagerRights Rights)
  578. {
  579. IntPtr scman = OpenSCManager(null, null, Rights);
  580. if (scman == IntPtr.Zero)
  581. {
  582. throw new ApplicationException("Could not connect to service control manager.");
  583. }
  584. return scman;
  585. }
  586. }
  587. }
Advertisement
Add Comment
Please, Sign In to add comment