ServiceManager/es: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: ServiceManager/es
| Old | New | Line | |
|---|---|---|---|
| 1 | + | *(Windows only)* | |
| 2 | + | ||
| 3 | + | ## ServiceManager (Gestor de Servicios) | |
| 4 | + | ||
| 5 | + | Bajo Windows existe un paquete extra (fcl-extra package) llamado ServiceManager. | |
| 6 | + | ||
| 7 | + | El siguiente ejemplo chequea si está ejecutándose el servicio SamSs (Security Accounts Manager, que debería estar siempre arrancado). (equivalente en línea de mandatos de sc query samss). | |
| 8 | + | ||
| 9 | + | ## Nombre de Servicio | |
| 10 | + | ||
| 11 | + | Debes tener en cuenta que si desarrollas tu propio servicio utilizando el paquete Lazdaemon entonces el nombre que se le asigne a dicho servicio tiene su importancia. Mientras que los mandatos **net start** y **net stop** utilizan el servicio mostrar nombre, el mandato **sc** y el código que se muestra más abajo utilizan el nombre de servicio interno. El nombre mostrado es que el se tiene en la propiedad "Display Name" del elemento creado en los elementos DaemosDefs. El nombre del servicio es la propiedad "Name" de dicho elemento. El nombre mostrado es el que se muestra actualmente en la columna **Name** por medio del applet de MS services manager (services.msc). Vamos a utilizar el ejemplo para clarificar esto. Se asume que has escrito una aplicación servicio llamada myService.exe en la cual hay un elemento en DaemosDefs. El elemento tienen por nombre "MyServ" y la propiedad asociada "DisplayName" tiene el valor "Internal build service". Utilizando la línea de mandatos como administrador puedes: | |
| 12 | + | ||
| 13 | + | ## Gestor de servicios utilizando la consola | |
| 14 | + | ||
| 15 | + | Para esto vas a necesitar tener funcionando alguno de los siguientes : Microsoft .Net Framework 4.5.2 (Web Installer) para Vista SP2, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2008 SP2, Windows Server 2008 R2 SP1, Windows Server 2012 o bien Windows Server 2012 R2. | |
| 16 | + | ||
| 17 | + | Tienes que tener soporte en el promt de mandatos con .Net SDK para instalar el servicio en tu máquina local. | |
| 18 | + | ||
| 19 | + | 1\. Llama al prompt de mandatos SDK, seguido de Start\>All Programs\>Microsoft .NET Framework SDK v2.0\>SDK Command prompt | |
| 20 | + | ||
| 21 | + | - **Instala el servicio:** | |
| 22 | + | ||
| 23 | + | ```dos | |
| 24 | + | \tu\trayecto\a\tu\aplicacion\myService.exe --install | |
| 25 | + | rem .... o también funciona con /install, -install | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | - **Activa el servicio:** | |
| 29 | + | ||
| 30 | + | En estos mandatos no olvides las **dobles comillas** cuando se necesiten múltiples palabras. | |
| 31 | + | ||
| 32 | + | ```dos | |
| 33 | + | net start "Internal build service" | |
| 34 | + | rem .... o alternativamente: | |
| 35 | + | sc start "MyServ" | |
| 36 | + | ``` | |
| 37 | + | ||
| 38 | + | - **Para detener el servicio:** | |
| 39 | + | ||
| 40 | + | ```dos | |
| 41 | + | net stop '''"Internal build service"''' | |
| 42 | + | rem ... o alternativamente | |
| 43 | + | sc stop "'''MyServ'''" | |
| 44 | + | ``` | |
| 45 | + | ||
| 46 | + | ## Código ejemplo | |
| 47 | + | ||
| 48 | + | Dicho esto, el fragmento de código para llamara la función de abajo debería ser en nuestro caso: | |
| 49 | + | ||
| 50 | + | Programa de ejemplo: | |
| 51 | + | ||
| 52 | + | ``` pascal | |
| 53 | + | program ServiceTest; | |
| 54 | + | // Chequea si un cierto proceso está corriendo. | |
| 55 | + | {$mode objfpc}{$H+} | |
| 56 | + | uses | |
| 57 | + | Classes, | |
| 58 | + | SysUtils, | |
| 59 | + | ServiceManager, | |
| 60 | + | JwaWinSvc {para declaraciones de servicios}; | |
| 61 | + | ||
| 62 | + | function IsServiceRunning(ServiceName: string): boolean; | |
| 63 | + | {Chequea si un servicio Windows está corriendo} | |
| 64 | + | var | |
| 65 | + | Services: TServiceManager; | |
| 66 | + | ServiceStatus: TServiceStatus; | |
| 67 | + | begin | |
| 68 | + | //Chequea por la existencia de servicios. | |
| 69 | + | //equivalente a sc query <nombredeservicio> | |
| 70 | + | Services := TServiceManager.Create(nil); | |
| 71 | + | try | |
| 72 | + | try | |
| 73 | + | Services.Acces := SC_MANAGER_CONNECT; //Note typo in property. | |
| 74 | + | //NO necesitamos más permisos de accesos que este; por defecto | |
| 75 | + | //servicemanager trata de obtener acceso total. | |
| 76 | + | Services.Connect; //Ahora conecta con el nivel de acceso requerido. | |
| 77 | + | Services.GetServiceStatus(ServiceName, ServiceStatus); | |
| 78 | + | if ServiceStatus.dwCurrentState = SERVICE_RUNNING then | |
| 79 | + | begin | |
| 80 | + | Result := True; | |
| 81 | + | end | |
| 82 | + | else | |
| 83 | + | begin | |
| 84 | + | Result := False; | |
| 85 | + | end; | |
| 86 | + | Services.Disconnect; | |
| 87 | + | except | |
| 88 | + | on E: EServiceManager do | |
| 89 | + | begin | |
| 90 | + | // ¿Puede un servicio perdido lanzar una excepción de handle perdido? ¿No? | |
| 91 | + | {LogOutput('Error getting service information for ' + ServiceName + | |
| 92 | + | '. Technical details: ' + E.ClassName + '/' + E.Message);} | |
| 93 | + | Result := False; | |
| 94 | + | raise; //relanza la excepción original. | |
| 95 | + | end; | |
| 96 | + | on E: Exception do | |
| 97 | + | begin | |
| 98 | + | {LogOutput('Error obteniendo información de servicio para ' + ServiceName + | |
| 99 | + | '. Detalles técnicos: ' + E.ClassName + '/' + E.Message); | |
| 100 | + | } | |
| 101 | + | Result := False; | |
| 102 | + | raise; //relanza excepción original. | |
| 103 | + | end; | |
| 104 | + | end; | |
| 105 | + | finally | |
| 106 | + | Services.Free; | |
| 107 | + | end; | |
| 108 | + | end; | |
| 109 | + | ||
| 110 | + | const | |
| 111 | + | ServiceToTest = 'SamSs'; | |
| 112 | + | ||
| 113 | + | //Security Accounts Manager, debería estar corriendo, al menos en Vista. | |
| 114 | + | begin | |
| 115 | + | WriteLn('Starting test for ' + ServiceToTest + ' service.'); | |
| 116 | + | if IsServiceRunning(ServiceToTest) then | |
| 117 | + | begin | |
| 118 | + | WriteLn('The ' + ServiceToTest + ' el servicio está corriendo'); | |
| 119 | + | end | |
| 120 | + | else | |
| 121 | + | begin | |
| 122 | + | WriteLn('The ' + ServiceToTest + ' el servicio no está corriendo'); | |
| 123 | + | end; | |
| 124 | + | end. | |
| 125 | + | ``` | |
| 126 | + | ||
| 127 | + | ## Funciones, constantes y tipos: | |
| 128 | + | ||
| 129 | + | function ServiceStateToString (AState: DWord): String | |
| 130 | + | ||
| 131 | + | const ServiceTypes = Array \[0..3\] of Word | |
| 132 | + | ||
| 133 | + | function ServiceTypeToString (AType: DWord): String | |
| 134 | + | ||
| 135 | + | const StartErrors = Array \[0..3\] of DWord | |
| 136 | + | ||
| 137 | + | const StartTypes = Array \[0..4\] of DWord | |
| 138 | + | ||
| 139 | + | type TServiceDescriptor = record | |
| 140 | + | ||
| 141 | + | type TServiceEntries = class (TOwnedCollection) | |
| 142 | + | ||
| 143 | + | type TServiceEntry = class (TCollectionItem) | |
| 144 | + | ||
| 145 | + | type TServiceManager = class (Tcomponent) | |
| 146 | + | ||
| 147 | + | function ControlAceptedToString (AValue: DWord): String | |
| 148 | + | ||
| 149 | + | type EServiceManager = class (Exception) | |
| 150 | + | ||
| 151 | + | function IsInteractiveService (AType: DWord): Boolean | |
| 152 | + | ||
| 153 | + | ## Ver también | |
| 154 | + | ||
| 155 | + | - [[http://wiki.lazarus.freepascal.org/Daemons and Services/es Demonios y Servicios]] | |
| 156 | + | ||
| 157 | + | --- | |
| 158 | + | *From the Free Pascal wiki, page "ServiceManager/es", as it stood on 2022-01-09 after a change by Slawek, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
