Windows 2000 / XP et 2003 prennent en charge quelque chose appelé "Programmes de service".
(1) Vous pouvez fonctionner sans vous connecter au système.
(2) Ayez des privilèges système.
Lorsque je développais un projet de décor pour une entreprise en 2003, j'ai écrit des téléchargements de cure-de suite et des services multimédias.
Exécutez Delphi7, sélectionnez le fichier de menu -> Nouveau -> Autre ---> Application de service. Framework.
(1) DisplayName: le nom d'affichage du service
(2) Nom: Nom du service.
Ici, nous modifions la valeur de DisplayName en "Delphi Service Demo" et le nom de "Delphitervice". est situé. Le service et l'état actuel seront affichés. Retournez à l'IDE de Delphi7.
Notre plan est d'ajouter une fenêtre principale pour ce service. fonction.
En fait, ne pensez pas que le programme de service fonctionne sur Winlogon Desktop. coché.
Fichier -> Nouveau -> Le formulaire ajoute une fenêtre frmmain au service, enregistre l'unité en tant qu'unité_frmmain et définit cette fenêtre à créer manuellement.
UNIT UNIT_MAIN;
interface
usages
Windows, messages, sysutils, classes, graphiques, contrôles, svcmgr, dialogs, unit_frmmain;
taper
Tdelphiservice = classe (tService)
Procédure ServiceContinue (expéditeur: tService; var suite: booléen);
Procédure ServiceExECute (expéditeur: tService);
Procédure ServicePause (expéditeur: tService; Var pause: booléen);
Procédure ServiceShutdown (expéditeur: tService);
Procédure ServiceStart (expéditeur: tService; var démarré: booléen);
Procédure ServiceStop (expéditeur: tService; var arrêté: booléen);
Privé
{Déclarations privées}
publique
fonction getServiceController: tServiceController;
{Déclarations publiques}
fin;
var
Delphitervice: tdelphitervice;
Frmmain: tfrmmain;
Mise en œuvre
{$ R * .dfm}
Procédure ServiceController (CtrlCode: DWORD);
Commencer
DelphiService.Controller (CtrlCode);
fin;
fonction tdelphiservice.getServiceController: tServiceController;
Commencer
Résultat: = ServiceController;
fin;
Procédure tdelphiService.ServiceContinue (expéditeur: tService;
var suite: booléen);
Commencer
Bien que non terminé
Commencer
Sommeil (10);
ServiceThread.ProcessRequests (false);
fin;
fin;
Procédure tdelphiService.ServiceExecute (expéditeur: tService);
Commencer
Bien que non terminé
Commencer
Sommeil (10);
ServiceThread.ProcessRequests (false);
fin;
fin;
Procédure tdelphiservice.servicePause (expéditeur: tService;
var pause: booléen);
Commencer
Pause: = true;
fin;
Procédure tdelphiService.ServiceShutdown (expéditeur: tService);
Commencer
gbcanclose: = true;
Frmmain.free;
Statut: = csstopped;
ReportStatus ();
fin;
Procédure tdelphiService.ServiceStart (expéditeur: tService;
Var démarré: booléen);
Commencer
Démarré: = true;
Svcmgr.Application.CreateForm (tfrmmain, frmmain);
gbcanclose: = false;
Frmmain.hide;
fin;
Procédure tdelphiservice.serviceStop (expéditeur: tService;
var arrêté: booléen);
Commencer
Arrêté: = true;
gbcanclose: = true;
Frmmain.free;
fin;
fin.
L'unité de fenêtre principale est la suivante:
UNIT UNIT_FRMMain;
interface
usages
Windows, messages, systèmes, variantes, classes, shellapi, graphiques, contrôles, formulaires,
Dialogues, extctrls, stdctrls;
const
Wm_trayicon = wm_user + 1234;
taper
Tfrmmain = classe (tform)
Timer1: Ttimer;
Button1: Tbutton;
Procédure FormCreate (expéditeur: tobject);
Procédure FormCloseQuery (expéditeur: tobject; var conserve: booléen);
Procédure FormDestroy (expéditeur: tobject);
Procédure Timer1Timer (expéditeur: tobject);
Procédure Button1Click (expéditeur: tobject);
Privé
{Déclarations privées}
ICONDATA: TnotifyIcondata;
procédure addicontotray;
Procédure DeliConfromtray;
Procédure TrayiConMessage (var msg: tMessage);
Procédure sysbuttonmsg (var msg: tMessage);
publique
{Déclarations publiques}
fin;
var
Frmmain: tfrmmain;
Gbcanclose: Boolean;
Mise en œuvre
{$ R * .dfm}
procédure tfrmmain.formCreate (expéditeur: tobject);
Commencer
FormStyle: = fsstayontop; {Front de fenêtre}
Setwindowlong (application.handle, gwl_exstyle, ws_ex_toolwindow);
gbcanclose: = false;
TIMER1.Interval: = 1000;
Timer1.enabled: = true;
fin;
Procédure tfrmmain.formCloseQuery (expéditeur: tobject; var conserve: booléen);
Commencer
Conserve: = gbcanclose;
Si cela ne peut pas conserver alors
Commencer
Cacher;
fin;
fin;
Procédure tfrmmain.formDestroy (expéditeur: tobject);
Commencer
Timer1.enabled: = false;
Deliconfromtray;
fin;
procédure tfrmmain.addiContotray;
Commencer
Zeromemory (@icondata, sizeof (tnotifyIcondata));
IConData.cbSize: = sizeof (tnotifyIConData);
Icondata.wnd: = manche;
Icondata.uid: = 1;
Icondata.uflags: = nif_message ou nif_icon ou nif_tip;
Icondata.ucallbackMessage: = wm_trayicon;
IConData.hicon: = application.icon.handle;
Icondata.sztip: = 'Delphi Service Demo Program';
Shell_notifyicon (NIM_ADD, @ICONDATA);
fin;
Procédure tfrmmain.deliconFromtray;
Commencer
Shell_notifyicon (nim_delete, @icondata);
fin;
procédure tfrmmain.sysbuttonmsg (var msg: tmessage);
Commencer
if (msg.wparam = sc_close) ou
(Msg.wparam = sc_minimize) puis masquer
sinon hérité; // effectuer l'action par défaut
fin;
procédure tfrmmain.trayiConMessage (var msg: tMessage);
Commencer
if (msg.lparam = wm_lbuttondblclk) alors show ();
fin;
procédure tfrmmain.timer1timer (expéditeur: tobject);
Commencer
Addicontotray;
fin;
Procédure Sendhokkey; stdcall;
var
Hdesk_wl: hdesk;
Commencer
Hdesk_wl: = openDesktop ('winlogon', 0, false, Desktop_JournalPlayback);
if (hdesk_wl <> 0) alors
if (setThreadDeskTop (hdesk_wl) = true) puis
PostMessage (hwnd_broadcast, wm_hotkey, 0, makelong (mod_alt ou mod_control, vk_delete));
fin;
procédure tfrmmain.button1click (expéditeur: tobject);
var
DwThreaDID: DWORD;
Commencer
CreateTheRad (nil, 0, @sendhokkey, nil, 0, dwthaRedid);
fin;
fin.
Remplir:
(1) Pour plus de programmes de démonstration du programme de service, veuillez visiter l'URL suivante: http://www.torry.net/pages.php?id=226, qui contient plusieurs codes qui montrent comment contrôler et gérer les services système.
(2) N'oubliez pas: Windows a en fait plusieurs ordinateurs de bureau. Il est sur le bureau du protecteur d'écran.
(3) Il existe également une méthode de commutation dynamique pour l'interaction entre le programme de service et le bureau.
unité desservicesktop;
interface
fonction initservicedesktop: booléen;
Procédure DonerservicedSktop;
Mise en œuvre
utilise des fenêtres, des sysutils;
const
DefaultWindowStation = 'WinSta0';
DefaultDesktop = 'Default';
var
Hwinstasave: Hwinsta;
Hdesksave: Hdesk;
Hwinstauser: Hwinsta;
Hdeskuser: Hdesk;
fonction initservicedesktop: booléen;
var
DwThreaDID: DWORD;
Commencer
DwThreaDID: = getCurrentThreaDID;
// Assurer la connexion à la station de fenêtre de service et au bureau, et
// GAGEZ LEURS PRIBLES.
hwinstasave: = getProcessWindowStation;
hdesksave: = getThreadDeskTop (dwThreaDID);
hwinstauser: = openwindowStation (defaultwindowStation, false, maximum_allowed);
Si hwinstauser = 0 alors
Commencer
OutputDebugString (PCHA ('OpenWindowStation a échoué' + syserrorMessage (getlasterror)));
Résultat: = false;
sortie;
fin;
Si ce n'est pas SetProcessWindowStation (hwinstauser) alors
Commencer
OutputDebugString ('setProcessWindowStation a échoué');
Résultat: = false;
sortie;
fin;
hdeskuser: = opendeSktop (defaultDesktop, 0, false, maximum_allowed);
Si hdeskuser = 0 alors
Commencer
OutputDebugString («OpenDesktop a échoué»);
SetProcessWindowStation (Hwinstasave);
ClosewindowStation (Hwinstauser);
Résultat: = false;
sortie;
fin;
Résultat: = setThreadDeskTop (hdeskuser);
Si ce n'est pas les résultats, alors
OutputDebugString (pChar ('setThreadDesktop' + syserrorMessage (getlasterRor)));
fin;
Procédure DonerservicedSktop;
Commencer
// Restaurer la station de fenêtre et le bureau.
SetThreadDesktop (HdeskSave);
SetProcessWindowStation (Hwinstasave);
Si hwinstauser <> 0 alors
ClosewindowStation (Hwinstauser);
Si hdeskuser <> 0 alors
CLOLESKTOP (Hdeskuser);
fin;
Initialisation
Initservicedesktop;
Finalisation
DaiservicedEdesktop;
fin.
Pour un code de démonstration plus détaillé, veuillez vous référer à: http://www.torry.net/samples/samples/os/isarticle.zip
(4) Comment ajouter des descriptions de service sur la façon d'installer un service. Nous sommes maintenant situés dans HKEY_LOCAL_MACHINE / System / ControlSet001. Suit:
unité winsvcex;
interface
Utilise Windows, WINSVC;
const
//
// Service Config Info Niveaux
//
Service_config_description = 1;
Service_config_failure_actions = 2;
//
// Nom de la DLL des fonctions importées
//
Advapidll = 'advapi32.dll';
taper
//
// chaîne de description du service
//
Plservicedescriptiona = ^ tServicedEsseScriptiona;
Psyservicedescriptionw = ^ tServicedEScriptionw;
PsyservicedesScription = psyservicedescriptiona;
{$ Externalsym _Service_descriptiona}
_Service_Descriptiona = Record
LPDescription: Pansichar;
fin;
{$ Externalsym _Service_descriptionw}
_Service_descriptionw = enregistrer
LPDescription: Pwidechar;
fin;
{$ Externalsym _Service_description}
_Service_Description = _Service_Descriptiona;
{$ Externalsym Service_Descriptiona}
Service_Descriptiona = _Service_Descriptiona;
{$ Externalsym Service_Descriptionw}
Service_DescriptionW = _Service_DescriptionW;
{$ Externalsym Service_Description}
Service_Description = _Service_Descriptiona;
TServiceDescriptiona = _Service_Descriptiona;
TServiceDescriptionw = _Service_Descriptionw;
TServiceDescription = tServicedScriptiona;
//
// Actions à entreprendre l'échec du service
//
{$ Externalsym _sc_action_type}
_Sc_action_type = (sc_action_none, sc_action_restart, sc_action_reboot, sc_action_run_command);
{$ Externalsym sc_action_type}
Sc_action_type = _sc_action_type;
PServiceAction = ^ tServiceAction;
{$ Externalsym _sc_action}
_Sc_action = enregistrer
atype: sc_action_type;
Retard: DWORD;
fin;
{$ Externalsym sc_action}
Sc_action = _sc_action;
TServiceAction = _sc_action;
PSERVICEFAILUREACTIONSA = ^ TSERVICEFAILUREACTIONSA;
PSERVICEFAILUREACTIONSW = ^ TSERVICEFAILUREACTIONSW;
PSERVICEFAILUREACTIONS = PSERVICEFAILUREACTIONSA;
{$ Externalsym _service_failure_actionsa}
_Service_Failure_Actionsa = Record
dwresetperiod: dword;
lprebootmsg: LPSTR;
LPCommand: LPSTR;
CACTIONS: DWORD;
lpsaactions: ^ SC_ACTION;
fin;
{$ Externalsym _service_failure_actionsw}
_Service_Failure_ActionSW = Record
dwresetperiod: dword;
lprebootmsg: lpwstr;
lpcommand: lpwstr;
CACTIONS: DWORD;
lpsaactions: ^ SC_ACTION;
fin;
{$ Externalsym _service_failure_actions}
_Service_Failure_Actions = _Service_Failure_Actionsa;
{$ Externalsym Service_Failure_Actionsa}
Service_Failure_Actionsa = _Service_Failure_Actionsa;
{$ Externalsym Service_Failure_ActionSW}
Service_Failure_ActionSW = _Service_Failure_ActionSW;
{$ Externalsym service_failure_actions}
Service_failure_actions = _service_failure_actionsa;
TServiceFailureActionsa = _Service_Failure_Actionsa;
TServiceFailureActionsw = _Service_failure_ActionSw;
TServiceFailureActions = tServiceFailureActionsa;
////////////////////////////////////////////////////////////////////////// / ////////////////////////////////////////////////////////////////////////// / ////////
// prototypes de fonction API
////////////////////////////////////////////////////////////////////////// / ////////////////////////////////////////////////////////////////////////// / ////////
TQueryServiceConfig2 = fonction (hService: sc_handle; dwinfolevel: dword; lpbuffer: pointeur;
CBBUFSIZE: DWORD;
TchangeServiceConfig2 = fonction (hService: sc_handle; dwinfolevel: dword; lpinfo: pointeur): bool;
var
HDLL: Thandle;
Libloaded: Boolean;
var
OsversionInfo: TosversionInfo;
{$ Externalsym queyserviceConfig2a}
QuereyserviceConfig2a: tQueryServiceConfig2;
{$ Externalsym queyserviceConfig2w}
QuereyserviceConfig2w: tQueryServiceConfig2;
{$ Externalsym queyserviceConfig2}
QuereyServiceConfig2: tQueryServiceConfig2;
{$ Externalsym changeserviceConfig2a}
ChangeServiceConfig2a: TchangeServiceConfig2;
{$ Externalsym changeserviceConfig2w}
ChangeServiceConfig2w: TchangeServiceConfig2;
{$ Externalsym changeserviceConfig2}
ChangeServiceConfig2: TchangeServiceConfig2;
Mise en œuvre
Initialisation
OsversionInfo.dwosversionInfosize: = sizeof (OsversionInfo);
GetVersionEx (OsversionInfo);
if (osversionInfo.dwplatformId = ver_platform_win32_nt) et (osversioninfo.dwmajorversion> = 5) alors
Commencer
Si hdll = 0 alors
Commencer
hdll: = getModuleHandle (advapidll);
Libloaded: = false;
Si hdll = 0 alors
Commencer
hdll: = loadLibrary (advapidll);
Libloaded: = true;
fin;
fin;
Si hdll <> 0 alors
Commencer
@ QueryServiceConfig2a: = getProcAddress (hdll, 'queryServiceConfig2a');
@ QueryServiceConfig2w: = getProcAddress (hdll, 'queryServiceConfig2w');
@ QueryServiceConfig2: = @ queryServiceConfig2a;
@ ChangeserviceConfig2a: = getProcAddress (hdll, 'changeserviceConfig2a');
@ ChangeserviceConfig2w: = getProcAddress (hdll, 'changeserviceConfig2w');
@ ChangeserviceConfig2: = @ changeserviceConfig2a;
fin;
fin
autre
Commencer
@ QueryServiceConfig2a: = nil;
@ QueryServiceConfig2w: = nil;
@ QueryServiceConfig2: = nil;
@ ChangeserviceConfig2a: = nil;
@ ChangeserviceConfig2w: = nil;
@ ChangeserviceConfig2: = nil;
fin;
Finalisation
if (hdll <> 0) et libloaded alors
Freelibrary (HDLL);
fin.
Unité WinntsService;
interface
usages
Windows, winsvc, winsvcex;
Fonction InstallService (const StrServiceName, strDisplayName, strDescription, strFileName: String): booléen;
// par exemple: installavice ('Service Name', 'Affichage Name', 'Description Informations', 'Service File');
Procédure UninstallService (strServiceName: String);
Mise en œuvre
Fonction Strlcopy (DEST: PHAR; const Source: Pchar; Maxlen: Cardinal): PHARD;
ASM
Push Edi
Pousser l'esi
Push EBX
MOV ESI, EAX
MOV EDI, EDX
MOV EBX, ECX
Xor Al, Al
Tester ECX, ECX
Jz @@ 1
Repne SCASB
JNE @@ 1
Inc Ecx
@@ 1: sous EBX, ECX
MOV EDI, ESI
MOV ESI, EDX
MOV EDX, EDI
MOV ECX, EBX
SHR ECX, 2
Représentant movsd
MOV ECX, EBX
Et ecx, 3
Rep movsb
Stosb
MOV EAX, EDX
Pop ebx
Pop esi
Edi pop
fin;
Fonction Strpchar (dest: phar; const Source: String): pChar;
Commencer
Résultat: = strlCopy (dest, pChar (source), longueur (source));
fin;
Fonction InstallService (const StrServiceName, strDisplayName, strDescription, strFileName: String): booléen;
var
// SS: TServiceStatus;
// pSTEMP: PCHA;
HSCM, HSCS: Thandle;
SRVDESC: PservevicedScription;
desc: String;
// srvtype: dword;
LPSERVICICEARGECTEURS: PCHER;
Commencer
Résultat: = false;
// ptestep: = nil;
// srvtype: = service_win32_own_process et service_interactive_process;
HSCM: = OpenScManager (Nil, Nil, SC_MANAGER_ALL_ACCESS); // Connectez la base de données du service
Si hscm = 0 alors sortez; // messagebox (hhandle, pChar (syserrorMessage (getlasterror)), 'Service Program Manager', MB_IConError + MB_TOPLost);
HSCS: = CreateService (// Créer une fonction de service
HSCM, // Gestion de gestion du contrôle des services
PChar (strServiceName), // Nom du service
PChar (strDisplayName), // le nom du service affiché
Service_All_Access, // Droits d'accès
Service_win32_own_process ou service_interactive_process, // type de service Service_win32_share_process
Service_auto_start, // type de démarrage
Service_error_ignore, // type de contrôle d'erreur
PHAR (StrFileName), // Programme de service
NIL, // Nom du service de groupe
NIL, // ID de groupe
Nil, // Services dépendants
nil, // démarrer le compte de service
nil); // démarrer le mot de passe du service
Si hscs = 0 alors sortez; // MessageBox (hhandle, pChar (syserrorMessage (getlasterror)), pChar (application.title), MB_IConError + MB_TOPLost);
si elle est affectée (changeserviceConfig2) alors
Commencer
desc: = copy (strdescription, 1 1024);
GetMem (srvDesc, sizeof (tServicedScription));
GetMem (srvdesc ^ .lpdescription, longueur (desc) + 1);
essayer
Strpcopy (srvdesc ^ .lpdescription, desc);
ChangeServiceConfig2 (HSCS, service_config_description, srvDesc);
Enfin
Freemem (SrvDesc ^ .lpDescription);
Freemem (SRVDESC);
fin;
fin;
lpServiceArgVectors: = nil;
Si ce n'est pas StariceService (HSCS, 0, LpServiceArgVecteurs) alors // Démarrez le service
Exit; //mesagebox(hhandle,pchar(SySerrorMessage(getLasterror)),pchar(Application.title),MB_IConError+MB_TOPLost);
CloseServiceHandle (HSCS);
Résultat: = true;
fin;
Procédure UninstallService (strServiceName: String);
var
Scmanager: sc_handle;
Service: SC_HANDLE;
Statut: tServiceStatus;
Commencer
Scmanager: = openscManager (nil, nil, sc_manager_all_access);
Si scmanager = 0 alors sortez;
essayer
Service: = OpenService (scmanager, pChar (strServiceName), service_all_access);
ControlService (Service, Service_Control_Stop, Status);
DeleteService (service);
CloserServiceHandle (service);
Enfin
CloserviceHandle (Scmanager);
fin;
fin;
fin.
(5) Comment fermer brutalement un programme de service et réaliser que la fonction de notre «boîte à outils NT» précédente?
utilise tlhelp32;
fonction killtask (exeFileName: String): entier;
const
Process_termiate = $ 0001;
var
Continuéop: bool;
Fsnapshothandle: thandle;
Fprocessentry32: tprocessentry32;
Commencer
Résultats: = 0;
Fsnapshothandle: = createToolHelp32Snapshot (th32cs_snapprocess, 0);
FProcessEntry32.dwsize: = sizeof (fProcessentry32);
Continuoop: = process32First (fsnapshothandle, fprocessentry32);
tandis que entier (continuéloop) <> 0 do
Commencer
if ((uppercase (extractFileName (fprocessentry32.szexefile)) =
Uppercase (exeFileName)) ou (uppercase (fprocessentry32.szexefile) =
Majuscules (exeFilename)) puis
Résultat: = entier (terminalProcess (
OpenProcess (process_termiate,
Bool (0),
Fprocessentry32.th32processsid),
0));
Continueop: = process32Next (fsnapshothandle, fprocessentry32);
fin;
CloseHandle (fsnapshothandle);
fin;
Cependant, pour le programme de service, il provoque un «accès refusé».
Fonction LotabledeBugPrivilege: Boolean;
Fonction ActiverPrivilege (HToken: Cardinal; privname: String; Benable: Boolean): Boolean;
var
Tp: token_privileges;
Dummy: Cardinal;
Commencer
Tp.privilegeCount: = 1;
LookupprivilegeValue (nil, phar (privname), tp.privileges [0] .luid);
Si Benable alors
Tp.privileges [0] .Attributes: = se_privilege_enabled
else tp.privileges [0] .Attributes: = 0;
Ajustement despririleges (htoken, false, tp, sizeof (tp), nil, mannequin);
Résultat: = getLasterRor = error_success;
fin;
var
Htoken: Cardinal;
Commencer
OpenProcessToken (getCurrentProcess, token_adjust_privileges, htoken);
Résultat: = ActiverPrivilege (htoken, «Sedebugprivilege», true);
Closehandle (htoken);
fin;
Comment utiliser:
Activés d'activation
Killtask ('xxxx.exe'); // Fermez le programme de service.
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ ----------