Windows 2000/XP y 2003 admiten algo llamado "programas de servicio".
(1) Puede ejecutar sin iniciar sesión en el sistema.
(2) Tener privilegios del sistema.
Cuando estaba desarrollando un proyecto de caja establecida para una empresa en 2003, escribí cargas de curso y servicios de medios.
Ejecute Delphi7, seleccione el archivo de menú-> nuevo-> OTRO ---> Aplicación de servicio. Marco.
(1) Nombre de pantalla: el nombre de visualización del servicio
(2) Nombre: Nombre del servicio.
Aquí cambiamos el valor de DisplayName a "Delphi Service Demo" y el nombre a "Delphiservice". está ubicado. El servicio y el estado actual se mostrarán. Vuelve al ide de Delphi7.
Nuestro plan es agregar una ventana principal para este servicio. función.
De hecho, no piense que el programa de servicio funcione en WinloGon Desktop. tictac. ¿Qué debo hacer?
Archivo-> nuevo-> Formulario agrega una ventana frmMain al servicio, guarda la unidad como unit_frmmain y establece esta ventana para ser creada manualmente.
Unidad Unidad_Main;
interfaz
usos
Windows, mensajes, sysutils, clases, gráficos, controles, SVCMGR, diálogos, unit_frmmain;
tipo
Tdelphiservice = class (tservice)
procedimiento ServiceContinue (remitente: TService; var continúa: booleano);
Procedimiento ServiceExCute (remitente: tservice);
Procedimiento ServicePause (remitente: tservice; var pause: boolean);
Procedimiento ServicesHutdown (remitente: TService);
Procedimiento ServiceStart (remitente: TService; var iniciado: booleano);
procedimiento ServiceStop (remitente: tservice; var detenido: booleano);
Privado
{Declaraciones privadas}
público
función getServiceController: tserviceController;
{Declaraciones públicas}
fin;
varilla
Delphiservice: tdelphiservice;
FrMMain: TFRMMain;
Implementación
{$ R *.dfm}
procedimiento ServiceController (CtrlCode: DWord);
Comenzar
Delphiservice.controller (ctrlcode);
fin;
función tdelphiservice.getServiceController: tserviceController;
Comenzar
Resultado: = ServiceController;
fin;
procedimiento tdelphiservice.serviceContinue (remitente: tservice;
var continúa: booleano);
Comenzar
Mientras que no se termina do
Comenzar
Dormir (10);
Servicethread.processRequests (falso);
fin;
fin;
procedimiento tdelphiservice.serviceExecute (remitente: tservice);
Comenzar
Mientras que no se termina do
Comenzar
Dormir (10);
Servicethread.processRequests (falso);
fin;
fin;
procedimiento tdelphiservice.servicePause (remitente: tservice;
Var Pause: Boolean);
Comenzar
Paused: = verdadero;
fin;
procedimiento tdelphiservice.serviceshutdown (remitente: tservice);
Comenzar
gbCancLose: = true;
FrMMain.
Estado: = csstopped;
ReportStatus ();
fin;
procedimiento tdelphiservice.serviceStart (remitente: tservice;
Var comenzó: booleano);
Comenzar
Iniciado: = verdadero;
Svcmgr.application.CreateForm (TFRMMain, frMMain);
gbCancLose: = false;
FrMMain. Hide;
fin;
procedimiento tdelphiservice.servicestop (remitente: tservice;
Var se detuvo: booleano);
Comenzar
Detenido: = verdadero;
gbCancLose: = true;
FrMMain.
fin;
fin.
La unidad principal de la ventana es la siguiente:
Unidad Unidad_frMMain;
interfaz
usos
Windows, mensajes, sysutils, variantes, clases, shellapi, gráficos, controles, formularios,
Diálogo, extctrls, stdctrls;
estúpido
Wm_trayicon = wm_user + 1234;
tipo
TFRMMAIN = CLASE (TFORM)
Temporizador1: ttimer;
Botón 1: tbutton;
procedimiento formulcreate (remitente: tobject);
procedimiento formcLosequery (remitente: tobject; var canc y boolean);
procedimiento FormDestrOY (remitente: tobject);
procedimiento temporizador1timer (remitente: tobject);
procedimiento botón1Click (remitente: tobject);
Privado
{Declaraciones privadas}
Icondata: tnotifyicondata;
Procedimiento Addicontotray;
procedimiento deliconfromtray;
Procedimiento TrayiConMessage (var msg: tmessage);
procedimiento sysbuttonmsg (var msg: tmessage);
público
{Declaraciones públicas}
fin;
varilla
FrMMain: TFRMMain;
GBCANCLOSE: booleano;
Implementación
{$ R *.dfm}
procedimiento tfrMMain.FormCreate (remitente: tobject);
Comenzar
FormStyle: = fsstayontop;
Setwindowlong (Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
gbCancLose: = false;
Temporizador1.interval: = 1000;
Timer1.enabled: = true;
fin;
Procedimiento tFRMMain.FormClosequery (remitente: tobject; var canc y boolean);
Comenzar
CANCLOSE: = GBCANCLOSE;
Si no cancela entonces
Comenzar
Esconder;
fin;
fin;
procedimiento tfrMMain.FormDestroy (remitente: tobject);
Comenzar
Timer1.enabled: = false;
DeliconFromTray;
fin;
Procedimiento TFRMMain.addicontotray;
Comenzar
Zeromemory (@icondata, sizeof (tnotifyicondata));
Icondata.cbsize: = sizeof (tnotifyicondata);
Icondata.wnd: = handle;
Icondata.uid: = 1;
Icondata.uflags: = nif_message o nif_icon o nif_tip;
Icondata.ucallbackMessage: = wm_trayicon;
Icondata.hicon: = Application.icon.handle;
Icondata.sztip: = 'Programa de demostración del servicio Delphi';
Shell_notifyicon (nim_add, @icondata);
fin;
procedimiento tFRMMain.deliconFromTray;
Comenzar
Shell_notifyicon (nim_delete, @icondata);
fin;
Procedimiento TFRMMAIN.SYSBUTTONMSG (var msg: tMessage);
Comenzar
if (msg.wparam = sc_close) o
(Msg.wparam = sc_minimize) luego esconderse
else heredado;
fin;
procedimiento tFRMMain.TrayiConMessage (var msg: tMessage);
Comenzar
if (msg.lparam = wm_lbuttondblclk) entonces show ();
fin;
procedimiento TFRMMain.Timer1Timer (remitente: tobject);
Comenzar
Addicontotray;
fin;
procedimiento sendHokkey; stdcall;
varilla
Hdesk_wl: hdesk;
Comenzar
HDESK_WL: = OPENDESKTOP ('WinLogon', 0, falso, escritorio_journalPlayBack);
if (hdesk_wl <> 0) entonces
if (setThreadDesktop (hdesk_wl) = true) entonces
PostMessage (hwnd_broadcast, wm_hotkey, 0, makelong (mod_alt o mod_control, vk_delete));
fin;
procedimiento TFRMMain.Button1Click (remitente: tobject);
varilla
dwthreadid: dword;
Comenzar
Createthread (nil, 0, @sendhokkey, nil, 0, dwthreadid);
fin;
fin.
Reponer:
(1) Para obtener más programas de demostración del programa de servicios, visite la siguiente URL: http://www.torry.net/pages.php?id=226, que contiene múltiples códigos que demuestran cómo controlar y administrar los servicios del sistema.
(2) Recuerde: Windows realmente tiene múltiples escritorios. Está en el escritorio protector de pantalla.
(3) También hay un método de conmutación dinámico para la interacción entre el programa de servicio y el escritorio.
Unidad Servicio de ServicioSktop;
interfaz
función initserviceSktop: boolean;
procedimiento DoneservateSktop;
Implementación
Utiliza ventanas, sysutils;
estúpido
Defaultwindowstation = 'winsta0';
DefaultDeskTop = 'default';
varilla
Hwinstasave: Hwinsta;
HDesksave: Hdesk;
Hwinstauser: Hwinsta;
HDeskuser: Hdesk;
función initserviceSktop: boolean;
varilla
dwthreadid: dword;
Comenzar
dwthreadid: = getCurrentThreadID;
// Asegurar la conexión a la estación y el escritorio de la ventana de servicio, y
// Guardar sus manijas.
hwinstasave: = getProcessWindowStation;
hdesksave: = getThreadDesktop (dwthreadid);
hwinstauser: = OpenWindowStation (defaultwindowstation, false, maximum_allowed);
Si hwinstauser = 0 entonces
Comenzar
OutputDebugString (pChar ('OpenWindowStation fallido' + syserrormessage (getLasterRor))));
Resultado: = falso;
salida;
fin;
Si no se setProcessWindowStation (hwinstauser) entonces
Comenzar
OutputDebugString ('setProcessWindowStation falló');
Resultado: = falso;
salida;
fin;
HDeskuser: = OpenDesktop (defaultDesktop, 0, falso, máximo_lowed);
Si hdeskuser = 0 entonces
Comenzar
OutputDebugString ('OpenDesktop fallido');
SetProcessWindowStation (hwinstasave);
CloseWindowstation (Hwinstauser);
Resultado: = falso;
salida;
fin;
Resultado: = setThreadDeskTop (HDeskuser);
Si no es resultados, entonces
OutputDebugString (pChar ('setThreadDesktop' + syserrormessage (getLasterRor)));
fin;
procedimiento DoneservateSktop;
Comenzar
// Restaurar la estación de ventana y el escritorio.
Setthreaddesktop (hdesksave);
SetProcessWindowStation (hwinstasave);
Si hwinstauser <> 0 entonces
CloseWindowstation (Hwinstauser);
Si hdeskuser <> 0 entonces
CloseDesktop (HDeskuser);
fin;
Inicialización
Initservicedesktop;
Finalización
DoneservateSktop;
fin.
Para obtener un código de demostración más detallado, consulte: http://www.torry.net/samples/samples/os/isarticle.zip
(4) Cómo agregar descripciones de servicio sobre cómo instalar un servicio. Acabo de estar ubicado en HKEY_LOCAL_MACHINE/SYSTEM/CONTROLSET001. Sigue:
Unidad Winsvcex;
interfaz
usa ventanas, winsvc;
estúpido
//
// niveles de información de configuración del servicio
//
Servicio_config_description = 1;
Servicio_config_failure_actions = 2;
//
// Nombre dll de las funciones importadas
//
Advapidll = 'advapi32.dll';
tipo
//
// String de descripción del servicio
//
PServiceScriptionA = ^tserviceScriptionA;
PServiceScedingw = ^tServiceDescriptionW;
PServiceScription = PServiceScriptionA;
{$ Externalsym _service_descriptiona}
_Service_descriptionA = registro
LpDescription: Pansichar;
fin;
{$ Externalsym _service_descriptionw}
_Service_descriptionw = registro
LpDescription: PWidechar;
fin;
{$ Externalsym _service_description}
_Service_Description = _Service_DescriptionA;
{$ Externalsym service_descriptiona}
Service_DescriptionA = _Service_DescriptionA;
{$ EXTERNALSYM SERVICE_DESCRIPTIVE}
Servicio_descriptionw = _service_descriptionw;
{$ EXTERNALSYM SERVICE_DESCRIPTION}
Service_Description = _Service_DescriptionA;
TserviceScriptionA = _Service_DescriptionA;
TservateScriptionw = _Service_Descriptionw;
TserviceScrited = tserviceScriptionA;
//
// Acciones para asumir la falla del servicio
//
{$ Externalsym _sc_action_type}
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
{$ Externa SC_ACTION_TYPE}
Sc_action_type = _sc_action_type;
PserviceAction = ^tserviceAction;
{$ Externalsym _sc_action}
_Sc_action = registro
atype: sc_action_type;
Retraso: dword;
fin;
{$ Externalsym sc_action}
Sc_action = _sc_action;
TserviceAction = _sc_action;
PServiceFailureActionsA = ^tserviceFailureActionsA;
PServiceFailureActionSW = ^tserviceFailureActions;
PServiceFailureActions = PServiceFailureActionsA;
{$ Externalsym _service_failure_acciones}
_Service_failure_acciones = registro
DWRESETPERIOD: DWORD;
LPREBOOTMSG: LPSTR;
LPCommand: LPSTR;
Cacciones: DWORD;
LPSAACTIONS: ^SC_ACTION;
fin;
{$ Externalsym _service_failure_actionsw}
_Service_failure_actionsw = registro
DWRESETPERIOD: DWORD;
LPREBOOTMSG: LPWSTR;
LPCOMMAND: LPWSTR;
Cacciones: DWORD;
LPSAACTIONS: ^SC_ACTION;
fin;
{$ Externalsym _service_failure_actions}
_Service_failure_actions = _Service_Failure_Actions;
{$ Externalsym service_failure_acciones}
Service_Failure_ActionsA = _Service_Failure_ActionSA;
{$ Externalsym Service_Failure_Actions}
Servicio_failure_actionsw = _service_failure_actionsw;
{$ Externalsym service_failure_actions}
Servicio_failure_actions = _Service_Failure_ActionSA;
TserviceFailureActionSa = _Service_Failure_Actions;
TServiceFailureActionSW = _Service_Failure_Actionsw;
TserviceFailureActions = tserviceFailureActionsA;
/////////////////////////////////////////////// /////////////////////////////////////////////// ///////
// Prototipos de funciones API
/////////////////////////////////////////////// /////////////////////////////////////////////// ///////
TqueryServiceConFig2 = function (hservice: sc_handle; dwinfolevel: dword; lpbuffer: pointer;
CBBUFSIZE: DWORD;
TchangeServiceConfig2 = function (hservice: sc_handle; dwinfolevel: dword; lpinfo: puntero): bool;
varilla
Hdll: Thandle;
Libloaded: boolean;
varilla
OsversionInfo: TosversionInfo;
{$ Externalsym QeryServiceConfig2a}
QueryServiceConfig2a: tqueryserviceconfig2;
{$ Externalsym QeryServiceConfig2w}
QueryServiceConfig2w: tQueryServiceConfig2;
{$ Externalsym QeryServiceConfig2}
QueryServiceConfig2: tQueryserviceconfig2;
{$ ExternalsymserviceConfig2a}
ChogiesServiceConFig2a: tchangeServiceConfig2;
{$ ExternalsymserviceConfig2w}
ChogiesServiceConFig2w: tchangeServiceConfig2;
{$ Externalsym ChogiesServiceConfig2}
ChogiesServiceConFig2: tchangeServiceConfig2;
Implementación
Inicialización
OsversionInfo.DwosVersionInfosize: = sizeOf (OsversionInfo);
GetVersionEx (OsversionInfo);
if (OsVersionInfo.dwplatformID = ver_platform_win32_nt) y (osversionInfo.dwmajorversion> = 5) Entonces
Comenzar
Si hdll = 0 entonces
Comenzar
hdll: = getModuleHandle (advapidll);
Libloaded: = false;
Si hdll = 0 entonces
Comenzar
hdll: = loadLibrary (advapidll);
Libloaded: = True;
fin;
fin;
Si hdll <> 0 entonces
Comenzar
@QueryServiceConFig2a: = getProcAddress (hdll, 'QueryServiceConFig2a');
@QueryServiceConFig2w: = getProcAddress (hdll, 'QueryServiceConfig2w');
@QueryServiceConFig2: = @QueryServiceConFig2a;
@ChangeserviceConFig2a: = getProcAddress (hdll, 'ChangeserviceConFig2a');
@ChangeserviceConFig2w: = getProcAddress (hdll, 'ChangeserviceConFig2w');
@ChangeserviceConFig2: = @ChangeserviceConFig2a;
fin;
fin
demás
Comenzar
@QueryServiceConFig2a: = nil;
@QueryServiceConfig2w: = nil;
@QueryServiceConFig2: = nil;
@ChangeserviceConFig2a: = nil;
@ChangeserviceConFig2w: = nil;
@ChangeserviceConFig2: = nil;
fin;
Finalización
if (hdll <> 0) y libloaded entonces
Freelibrary (hdll);
fin.
Unidad WinntService;
interfaz
usos
Windows, Winsvc, Winsvcex;
función installService (const strserviceName, strdisplayname, strDescription, strfilename: string): boolean;
// Ej.
procedimiento uninstallService (strserviceName: string);
Implementación
function strlCopy (des: pchar; constante: pchar; maxlen: cardinal): pchar;
ASM
EDI de empuje
Empujar ESI
Empujar ebx
Mov esi, eax
Mov edi, edx
Mov Ebx, ECX
Xor Al, Al
Prueba ECX, ECX
JZ @@ 1
Repne scasb
JNE @@ 1
Incx
@@ 1: Sub Ebx, ECX
Mov edi, esi
Mov esi, edx
Mov edx, edi
MoV ECX, EBX
Shr Ecx, 2
Representante Movsd
MoV ECX, EBX
Y ECX, 3
Representante Movsb
Stosb
Mov eax, edx
Pop ebx
Pop ESI
Pop EDI
fin;
función strpchar (des: pchar; const foute: string): pchar;
Comenzar
Resultado: = strlCopy (des, pChar (fuente), longitud (fuente));
fin;
función installService (const strserviceName, strdisplayname, strDescription, strfilename: string): boolean;
varilla
// ss: tservicestatus;
// pstemp: pchar;
HSCM, HSCS: Thandle;
SrvDesc: PServiceDescription;
Desc: cadena;
// srvtype: dword;
lpserviceargvectores: pchar;
Comenzar
Resultado: = falso;
// pstemp: = nil;
// srvtype: = servicio_win32_own_process y servicio_interactive_process;
HSCM: = OpenSCManager (nil, nil, sc_manager_all_access); // Conecte la base de datos del servicio
if hscm = 0 entonces salga; // MessageBox (HHANDLE, PCHAR (SYSERMORMESSAGE (getLasterRor)), 'Service Program Manager', mb_iconerror+mb_topmost);
HSCS: = CreateService (// Crear función de servicio
HSCM, // Manejo de gestión de control de servicio
PCHAR (strserviceName), // Nombre del servicio
Pchar (strdisplayname), // El nombre del servicio se muestra
Servicio_all_access, // Derechos de acceso
Servicio_win32_own_process o servicio_interactive_process, // Tipo de servicio Service_win32_share_process
Servicio_auto_start, // Tipo de inicio
Servicio_error_ignore, // Tipo de control de errores
PCHAR (STRFILENAME), // Programa de servicio
nulo, // Nombre del servicio grupal
nulo, // ID de grupo
Nil, // Servicios dependientes
nulo, // iniciar la cuenta de servicio
nulo);
if hscs = 0 entonces salga; // MessageBox (HHANDLE, PCHAR (SYSERROMESSAGE (getLasterRor)), pChar (Application.Title), MB_iConError+MB_TOPMOST);
Si se asigna (ChangsServiceConFig2) entonces
Comenzar
Desc: = copy (strDescription, 1,1024);
GetMem (srvdesc, sizeOf (tserviceedescription));
GetMem (srvDesc^.lpDescription, longitud (desc) + 1);
intentar
StrpCopy (srvDesc^.lpDescription, desc);
ChogiesServiceConFig2 (HSCS, Service_Config_Description, SRVDESC);
Finalmente
Freemem (srvdesc^.lpDescription);
Freemem (srvdesc);
fin;
fin;
lpServiceargVectors: = nil;
Si no StartService (HSCS, 0, LpServiceArgVectors) entonces // Inicie el servicio
Salir; //messageBox(hhandle,pchar(SySerMessage(getLasterRor),pchar(Application.title),mb_iconerror+mb_topmost);
CloseServiceHandle (HSCS);
Resultado: = verdadero;
fin;
procedimiento uninstallService (strserviceName: string);
varilla
ScManager: sc_handle;
Servicio: sc_handle;
Estado: Tservicestatus;
Comenzar
ScManager: = OpenSCManager (nil, nil, sc_manager_all_access);
Si scManager = 0 entonces salga;
intentar
Servicio: = OpenService (SCManager, PCHAR (STRServiceName), Service_all_Access);
ControlService (servicio, servicio_control_stop, status);
DeleteService (servicio);
CloseServiceHandle (Servicio);
Finalmente
CloseServiceHandle (scManager);
fin;
fin;
fin.
(5) ¿Cómo cerrar brutalmente un programa de servicio y darse cuenta de la función de nuestra "caja de herramientas NT" anterior?
usa tlhelp32;
función KillTask (ExeFileName: String): Integer;
estúpido
Process_merminate = $ 0001;
varilla
Continulueloop: Bool;
Fsnapshothandle: Thandle;
Fprocessentry32: tprocessentry32;
Comenzar
Resultados: = 0;
FSNAPSHOTHANDLE: = CreateToolHelp32SnapShot (th32cs_snapprocess, 0);
Fprocessentry32.dwsize: = sizeof (fprocessentry32);
Continueroop: = process32First (fsnapshothandle, fprocessentry32);
Mientras que entero (continuarioop) <> 0 do
Comenzar
if ((uppercase (ExtractFileName (fprocessentry32.szExefile)) =
Uppercase (exefileName)) o (uppercase (fprocessentry32.szexefile) =
Mayúscula (exefilename)) entonces
Resultado: = Integer (termineProcess (
OpenProcess (process_merminate,
Bool (0),
Fprocessentry32.th32processid),
0));
Continueroop: = process32Next (fsnapshothandle, fprocessentry32);
fin;
CloseHandle (fsnapshothandle);
fin;
Sin embargo, para el programa de servicio, provocará "acceso denegado".
function habiledeBugPrivilege: boolean;
function enablePrivilege (htoken: cardinal; privname: string; benable: boolean): boolean;
varilla
TP: token_privileges;
Dummy: Cardinal;
Comenzar
Tp.privilegecount: = 1;
LookUpPrivilegeValue (nil, pchar (privname), tp.privileges [0] .luid);
Si se puede ser así
Tp.privileges [0] .Attributes: = SE_PRIVILEGE_ENABLED
else tp.privileges [0] .Attributes: = 0;
Ajustar a los huellas (hToken, falso, tp, sizeOf (tp), nil, ficticia);
Resultado: = getLasterRor = ERROR_SUCCESS;
fin;
varilla
HToken: Cardinal;
Comenzar
OpenProcessToken (getCurrentProcess, token_adjust_privileges, htoken);
Resultado: = EnablePrivilege (HToken, 'SedebugPrivilege', verdadero);
CloseHandle (HToken);
fin;
Cómo usar:
HabiledeBugPrivilege; // Elevar permisos
KillTask ('xxxx.exe'); // Cierre el programa de servicio.
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ ----------