Windows 2000/XP und 2003 unterstützen sogenannte "Serviceprogramme".
(1) Sie können ohne Anmeldung im System laufen.
(2) Systemrechte haben.
Als ich 2003 ein Set-Top-Box-Projekt für ein Unternehmen entwickelte, schrieb ich Courseware-Uploads und Mediendienste.
Führen Sie Delphi7 aus, wählen Sie die Menüdatei-> Neu-> Service-Anwendung. Framework.
(1) DisplayName: Der Anzeigename des Dienstes
(2) Name: Dienstname.
Hier ändern wir den Wert von DisplayName in "Delphi Service Demo" und den Namen "Delphiservice". ist angezeigt. Service und aktueller Status werden jedoch angezeigt. Gehen Sie zurück zu Delphi7's IDE.
Unser Plan ist ein Hauptfenster für diesen Service. Funktion.
Denken Sie nicht, dass das Serviceprogramm auf Winlogon Desktop funktioniert. Ticked. Was soll ich tun?
Datei-> Neu-> Form fügt dem Dienst ein Fenster hinzu, speichert das Gerät als Unit_Frmmain und setzt dieses Fenster manuell erstellt.
UNIT UNIT_MAIN;
Schnittstelle
Verwendung
Windows, Nachrichten, Systeme, Klassen, Grafiken, Steuerelemente, SVCMGR, Dialoge, Unit_Frmmain;
Typ
TdelphiService = Klasse (TService)
procedure serviceContinue (Absender: TService; var Fortsetzung: boolean);
procedure ServiceExecute (Absender: TService);
VerfahrensdienstPause (Absender: TService; var pausiert: boolean);
Procedure ServicesHutdown (Absender: TService);
procedure servicestart (Absender: TService; var gestartet: boolean);
Procedure Servicestop (Absender: TService; var gestoppt: boolean);
Privat
{Private Deklarationen}
öffentlich
Funktion getServiceController: TServiceController;
{Öffentliche Erklärungen}
Ende;
var
Delphiservice: tdelphiService;
Frmmain: tfrmmain;
Durchführung
{$ R *.dfm}
procedure serviceController (StrlCode: DWORD);
Beginnen
DelPhIService.Controller (Strlcode);
Ende;
Funktion tdelphiService.getServiceController: TServiceController;
Beginnen
Ergebnis: = serviceController;
Ende;
Verfahren tdelphiService.ServiceContinue (Absender: TService;
var Fortsetzung: Boolean);
Beginnen
Während nicht beendet werden
Beginnen
Schlaf (10);
Servicethread.ProcessRequests (falsch);
Ende;
Ende;
Prozedur tdelphiService.ServiceExecute (Absender: TService);
Beginnen
Während nicht beendet werden
Beginnen
Schlaf (10);
Servicethread.ProcessRequests (falsch);
Ende;
Ende;
Prozedur tdelphiService.ServicePause (Absender: TService;
var pausiert: boolean);
Beginnen
Pausiert: = wahr;
Ende;
Prozedur tdelphIserservice.ServicesHutdown (Absender: TService);
Beginnen
gbcancrose: = true;
Frmmain.free;
Status: = cStoped;
ReportStatus ();
Ende;
Verfahren tdelphiService.servicestart (Absender: TService;
var begann: boolean);
Beginnen
Start: = wahr;
Svcmgr.application.createform (tfrmmain, frmmain);
gbcancsose: = false;
Frmmain.hide;
Ende;
Verfahren tdelphiService.servicestop (Absender: TService;
var gestoppt: boolean);
Beginnen
Gestoppt: = wahr;
gbcancrose: = true;
Frmmain.free;
Ende;
Ende.
Die Hauptfenstereinheit lautet wie folgt:
UNIT UNIT_FRMMAIN;
Schnittstelle
Verwendung
Fenster, Nachrichten, Systeme, Varianten, Klassen, Schellapi, Grafiken, Steuerelemente, Formulare,
Dialoge, extctrls, stdctrls;
Const
Wm_trayicon = wm_user + 1234;
Typ
Tfrmmain = class (tform)
Timer1: Timer;
Button1: Tbutton;
Prozedur Formcreate (Absender: Tobject);
VerfahrensformCloseQuery (Absender: Tobject; var canclose: boolean);
VerfahrensformularDestroy (Absender: Tobject);
Procedure Timer1Timer (Absender: Tobject);
PROCEDURE Taste1Click (Absender: Tobject);
Privat
{Private Deklarationen}
ICondata: tnotifyicondata;
Verfahrensmontage;
Verfahren deliconfromtray;
VerfahrenstrayiconMessage (var msg: tmessage);
Prozedur sysbuttonmsg (var msg: tmessage);
öffentlich
{Öffentliche Erklärungen}
Ende;
var
Frmmain: tfrmmain;
gbcancrose: boolean;
Durchführung
{$ R *.dfm}
procedure tfrmmain.formcreate (Absender: tobject);
Beginnen
FormStyle: = fsStayontop;
SetWindowlong (application.Handle, gwl_exStyle, WS_EX_TOOLWINDOW);
gbcancsose: = false;
Timer1.Interval: = 1000;
Timer1.Enabled: = true;
Ende;
procedure tfrmmain.formCloseQuery (Absender: tobject; var canclose: boolean);
Beginnen
Canclose: = gbcanclose;
Wenn nicht canclose dann
Beginnen
Verstecken;
Ende;
Ende;
Prozedur tfrmmain.FormDestroy (Absender: Tobject);
Beginnen
Timer1.Enabled: = false;
DelikonfromTray;
Ende;
Verfahren tfrmmain.addicontotray;
Beginnen
Zeromemory (@icondata, sizeof (tnotifyicondata));
Icondata.cbize: = sizeof (tnotifyicondata);
Icondata.wnd: = Handle;
Icondata.uid: = 1;
Icondata.ufags: = nif_message oder nif_icon oder nif_tip;
Icondata.ucallbackMessage: = wm_trayicon;
Icondata.hicon: = application.icon.handle;
Icondata.sztip: = 'Delphi Service Demo Program';
Shell_notifyicon (nim_add, @icondata);
Ende;
Verfahren tfrmmain.deliconfromTray;
Beginnen
Shell_notifyicon (nim_delete, @icondata);
Ende;
procedure tfrmmain.sysbuttonmsg (var msg: tmessage);
Beginnen
if (msg.wparam = sc_close) oder
(Msg.wparam = sc_minimize) und dann verstecken
sonst geerbt; // die Standardaktion ausführen
Ende;
procedure tfrmmain.trayiconMessage (var msg: tmessage);
Beginnen
if (msg.lparam = wm_lbuttondblclk) dann show ();
Ende;
procedure tfrmmain.timer1timer (Absender: tobject);
Beginnen
Sdicontotray;
Ende;
Verfahren sendHokkey; stdcall;
var
HDESK_WL: HDESK;
Beginnen
Hdesk_wl: = opendektop ('winlogon', 0, false, Desktop_journalPlayback);
if (hdesk_wl <> 0) dann
if (setThreadDesktop (hdesk_wl) = true) dann
PostMessage (hwnd_broadcast, wm_hotkey, 0, makelong (mod_alt oder mod_control, vk_delete));
Ende;
procedure tfrmmain.button1click (Absender: tobject);
var
dwthreadid: dword;
Beginnen
CreateThead (Nil, 0, @SendHokkey, Nil, 0, Dwthreadid);
Ende;
Ende.
Wieder auffüllen:
(1) Weitere Informationen zum Demonstrationsprogrammen für Serviceprogramme finden Sie in der folgenden URL: http://www.torry.net/pages.php?id=226, die mehrere Codes enthält, die zeigen, wie Systemdienste gesteuert und verwaltet werden.
(2) Bitte denken Sie daran: Windows hat beispielsweise mehrere Desktops. Es befindet sich auf dem Bildschirmschutzdesktop.
(3) Es gibt auch eine dynamische Schaltmethode für die Interaktion zwischen dem Serviceprogramm und dem Desktop.
Einheit Servicedesktop;
Schnittstelle
Funktion initservicedesktop: boolean;
Verfahren Doneservicedesktop;
Durchführung
verwendet Fenster, Systeme;
Const
DefaultWindowStation = 'WinSta0';
DefaultDesktop = 'Standard';
var
hwinstasave: hwinsta;
hdesksave: hdesk;
Hwinstauser: Hwinsta;
Hdeskuser: Hdesk;
Funktion initservicedesktop: boolean;
var
dwthreadid: dword;
Beginnen
dwthreadid: = getCurrentThreadid;
// Stellen Sie die Verbindung zur Servicefensterstation und zum Desktop sicher und sicher
// ihre Griffe speichern.
hwinstasave: = GetProcessWindowStation;
hdesksave: = GetThreadDesktop (dwthreadid);
hwinstauser: = openWindowStation (StandardwindowStation, Falsch, Maximum_allowed);
Wenn hwinstauser = 0 dann
Beginnen
Outputdebugstring (pChar ('OpenWindowStation fehlgeschlagen' + syserformessage (getlasterror));
Ergebnis: = falsch;
Ausfahrt;
Ende;
Wenn nicht setProcessWindowStation (Hwinstauser), dann dann
Beginnen
OutputDebugstring ('setProcessWindowStation fehlgeschlagen');
Ergebnis: = falsch;
Ausfahrt;
Ende;
hdeskuser: = opendektop (defaultDesktop, 0, falsch, maximum_allowed);
Wenn Hdeskuser = 0 dann
Beginnen
OutputDebugstring ('OpenKTOP fehlgeschlagen');
SetProcessWindowStation (hwinstasave);
CloseWindowstation (Hwinstauser);
Ergebnis: = falsch;
Ausfahrt;
Ende;
Ergebnis: = setThreadDesktop (hdeskuser);
Wenn nicht Ergebnisse, dann
OutputDebugstring (pChar ('setThreadDesktop' + syserformessage (getLasterror));
Ende;
Verfahren Doneservicedesktop;
Beginnen
// Fensterstation und Desktop wiederherstellen.
SetThreadDesktop (hdesksave);
SetProcessWindowStation (hwinstasave);
Wenn hwinstauser <> 0 dann
CloseWindowstation (Hwinstauser);
Wenn Hdeskuser <> 0 dann
Closedesktop (Hdeskuser);
Ende;
Initialisierung
Initservicedesktop;
Abschluss
Doneservicedesktop;
Ende.
Weitere detaillierteren Demonstrationscode finden Sie unter: http://www.torry.net/samples/samples/os/isarticle.zip
(4) So fügen Sie Service -Beschreibungen zur Installation eines Dienstes hinzu. Wir befinden uns gerade in HKEY_LOCAL_MACHINE/SYSTEM/CONTROLSET001. folgt:
Einheit Winsvcex;
Schnittstelle
verwendet Windows, Winsvc;
Const
//
// Service -Konfigurationsinformationen Level
//
Service_config_description = 1;
Service_config_failure_actions = 2;
//
// DLL Name der importierten Funktionen
//
Advapidll = 'advapi32.dll';
Typ
//
// Service Beschreibung Zeichenfolge
//
PERSICEUTESCRIPTIONA = ^TServicedescriptiona;
Pserditescriptionw = ^tservicedescriptionw;
PSERVICIUTESCRIPTION = PSERTIPICTESCRIPTIONA;
{$ Externalsym _service_descriptiona}
_Service_Descriptiona = Datensatz
LPDescription: Pansichar;
Ende;
{$ Externalsym _service_descriptionw}
_Service_Descriptionw = Datensatz
LPDescription: Pwidechar;
Ende;
{$ 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 = tservicedescriptiona;
//
// Maßnahmen zum Versagen des Dienstes übernehmen
//
{$ 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;
PERSIVICEAction = ^tserviceAction;
{$ Externalsym _sc_action}
_Sc_action = record
atype: sc_action_type;
Verzögerung: DWORD;
Ende;
{$ Externalsym sc_action}
Sc_action = _sc_action;
TServiceAction = _sc_action;
PSERVICEFAILEACTIONSA = ^TServiceFailureActionsa;
PSERVICEFAILEACTIONSW = ^TServiceFailureActionsSW;
PSERVICEFAILEACTIONS = PSERVICEFAILEACTIONSA;
{$ Externalsym _service_failure_actionsa}}
_Service_Failure_actionsa = Datensatz
DWRESETPERIOD: DWORD;
lprebootmsg: lpstr;
lpcommand: lpstr;
Kaktionen: DWORD;
lpSaactions: ^sc_action;
Ende;
{$ Externalsym _service_failure_actionsw}
_Service_Failure_actionsw = Record
DWRESETPERIOD: DWORD;
lprebootmsg: lpwstr;
lpcommand: lpwstr;
Kaktionen: DWORD;
lpSaactions: ^sc_action;
Ende;
{$ 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;
TServiceFailureActionsSW = _Service_Failure_ActionSW;
TServiceFailureActs = TServiceFailureActionsa;
////////////////////////////////////////////////// ////////////////////////////////////////////////// /////////
// API -Funktionsprototypen
////////////////////////////////////////////////// ////////////////////////////////////////////////// /////////
TQUERYServiceConfig2 = Funktion (HService: sc_handle; DwinFOLEVEL: DWORD; LPBUFFER: Zeiger;
CBBUFSIZE: DWORD;
TChangeServiceConfig2 = Funktion (HService: sc_handle; DwinFOLEVEL: DWORD; LPINFO: Zeiger): bool;
var
Hdll: Thandle;
LILBOODED: Boolean;
var
OsversionInfo: TosversionInfo;
{$ Externalsym QueryServiceConfig2a}
QueryServiceConfig2a: TqueryServiceConfig2;
{$ Externalsym QueryServiceConfig2w}
QueryServiceConfig2W: TqueryServiceConfig2;
{$ Externalsym QueryServiceConfig2}
QueryServiceConfig2: TqueryServiceConfig2;
{$ Externalsym idneServiceConfig2a}
ChangeServiceConfig2a: tchangeServiceConfig2;
{$ Externalsym idneServiceConfig2w}
ChangeServiceConfig2w: tchangeServiceConfig2;
{$ Externalsym idneServiceConfig2}
ChangeServiceConfig2: tchangeServiceConfig2;
Durchführung
Initialisierung
OsversionInfo.DWOSversionInfosize: = sizeof (OsversionInfo);
GetversionEx (OsversionInfo);
if (osversionInfo.dwPlatformID = ver_PLATFORM_WIN32_NT) und (OsversionInfo.dwmajorversion> = 5) dann
Beginnen
Wenn Hdll = 0 dann
Beginnen
hdll: = getModuleHandle (advapIdll);
Libloaden: = false;
Wenn Hdll = 0 dann
Beginnen
hdll: = loadlibrary (advapIdll);
Libloaden: = wahr;
Ende;
Ende;
Wenn Hdll <> 0 dann
Beginnen
@QueryServiceConfig2a: = getProcaddress (HDLL, 'queryServiceConfig2a');
@QueryServiceConfig2W: = getProcaddress (HDLL, 'queryServiceConfig2w');
@QueryServiceConfig2: = @queryServiceConfig2a;
@ChangeServiceConfig2a: = GetProcaddress (HDLL, 'ayagesServiceConfig2a');
@ChangeServiceConfig2w: = getProcaddress (HDLL, 'ayagesServiceConfig2w');
@ChangeServiceConfig2: = @ChangeServiceConfig2a;
Ende;
Ende
anders
Beginnen
@QueryServiceConfig2a: = nil;
@QueryServiceConfig2w: = nil;
@QueryServiceConfig2: = nil;
@ChangeServiceConfig2a: = nil;
@ChangeServiceConfig2w: = nil;
@ChangeServiceConfig2: = nil;
Ende;
Abschluss
if (hdll <> 0) und linaded dann
Freelibrary (HDLL);
Ende.
Einheit Winnntservice;
Schnittstelle
Verwendung
Windows, Winsvc, Winsvcex;
function installService (const StrserviceName, StrDisplayName, StrDescription, Strafilename: String): boolean;
// EG: InstallService ("Service Name", "Anzeigename", "Beschreibungsinformationen", "Dienstdatei");
Prozedur deinstallService (StrserviceName: String);
Durchführung
Funktion Strlcopy (dest: pchar; const Quelle: pchar; maxlen: kardinal): pchar;
Asm
Schieben edi
Schieben Sie ESI
EBX drücken
MOV ESI, EAX
MOV EDI, EDX
MOV EBX, ECX
Xor al, al
Test ECX, ECX
Jz @@ 1
Repne Scasb
Jne @@ 1
INC ECX
@@ 1: Sub Ebx, ECX
MOV EDI, ESI
MOV ESI, EDX
MOV EDX, EDI
MOV ECX, EBX
SHR ECX, 2
Rep Movsd
MOV ECX, EBX
Und Ecx, 3
Rep Movsb
STOSB
MOVE EAX, EDX
Pop ebx
Pop ESI
Pop EDI
Ende;
Funktion Strpchar (dest: pchar; const Quelle: String): pchar;
Beginnen
Ergebnis: = strlcopy (dest, pchar (Quelle), Länge (Quelle));
Ende;
function installService (const StrserviceName, StrDisplayName, StrDescription, Strafilename: String): boolean;
var
// ss: tservicestatus;
// pstemp: pchar;
HSCM, HSCs: Thandle;
SRVDESC: PSERVICIUTESCRIPTION;
Desc: String;
// srvType: dWord;
lpServiceargVectors: pchar;
Beginnen
Ergebnis: = falsch;
// pstemp: = nil;
// srvType: = service_win32_own_process und service_interactive_process;
HSCM: = OpenScmanager (NIL, NIL, SC_MANAGER_ALL_ACCESS); // Verbinden Sie die Dienstdatenbank
Wenn Hscm = 0 dann beenden; // MessageBox (Hhandle, pchar (syserRorMessage (getLasterror)), 'Service Program Manager', MB_ICONError+MB_TOP MOST);
HSCs: = createService (// Dienstfunktion erstellen
HSCM, // Service Control Management Handle
Pchar (StrserviName), // Service Name
Pchar (StrDisplayName), // Der angezeigte Dienstname
Service_all_access, // Zugriffsrechte
Service_win32_own_process oder service_interactive_process, // service type service_win32_share_process
Service_auto_start, // Starttyp
Service_error_ignore, // Fehlersteuerungstyp
Pchar (strFileName), // Service -Programm
NIL, // Gruppendienstname
Nil, // Gruppen -ID
NIL, // Abhängige Dienste
Nil, // das Servicekonto starten
nil); // das Service Passwort starten
Wenn HSCS = 0 dann beenden; // MessageBox (Hhandle, pchar (syserformessage (getLasterror)), pchar (application.title), mb_iconError+mb_top meiste);
Wenn zugewiesen (ayagesServiceConfig2), dann
Beginnen
Desc: = Copy (StrDescription, 1,1024);
GetMem (SRVDESC, sizeof (tServicedescription));
GetMem (srvdesc^.lpDescription, Länge (Desc) + 1);
versuchen
StrpCopy (srvdesc^.lpDescription, Desc);
ChangeServiceConfig2 (HSCs, service_config_description, srvdesc);
Endlich
Freemem (srvdesc^.lpDescription);
Freemem (srvdesc);
Ende;
Ende;
lpServiceargVectors: = nil;
Wenn nicht StartService (HSCs, 0, LpServiceargVectors), dann starten Sie den Dienst
Beenden;
CloseServiceHandle (HSCs);
Ergebnis: = wahr;
Ende;
Prozedur deinstallService (StrserviceName: String);
var
ScManager: sc_handle;
Service: sc_handle;
Status: Tservicestatus;
Beginnen
ScManager: = OpenScmanager (NIL, NIL, SC_MANAGER_ALL_ACCESS);
Wenn ScManager = 0 dann beenden;
versuchen
Service: = OpenService (ScManager, pchar (StrserviName), service_all_access);
ControlService (Service, Service_Control_Stop, Status);
DeleteService (Service);
ClosserviceHandle (Service);
Endlich
ClosserviceHandle (ScManager);
Ende;
Ende;
Ende.
(5) So schließen Sie ein Serviceprogramm brutal und erkennen Sie die Funktion unserer vorherigen "NT -Toolbox"?
verwendet tlhelp32;
Funktion Killtask (ExefileName: String): Ganzzahl;
Const
Process_termate = $ 0001;
var
Continueloop: bool;
Fsnapshothandle: Thandle;
FProcessEntry32: TProcessEntry32;
Beginnen
Ergebnisse: = 0;
Fsnapshothandle: = CreateToolHelp32Snapshot (Th32CS_SnApprocess, 0);
FProcessEntry32.dwsize: = sizeof (fprocessEntry32);
Continueloop: = process32First (fsnapshothandle, fprocessentry32);
während Ganzzahl (continueloop) <> 0 tun
Beginnen
if ((Großbuchstaben (extractFileName (fprocessEntry32.Szexefile)) =
Großbuchstaben (ExefileName)) oder (Großbuchstaben (fROCESSENTRY32.SZEXEFILE) =
Großbuchstaben (Exefilename)) dann
Ergebnis: = Integer (TerminateProcess (
OpenProcess (process_terate,
Bool (0),
FProcessEntry32.th32Processid),
0));
Continueloop: = process32Next (fsnapshotHandle, fprocessentry32);
Ende;
Nahe Handle (fsnapshothandle);
Ende;
Für das Serviceprogramm wird jedoch "Zugriff verweigert".
Funktion EnableDebugprivilege: Boolean;
Funktion enablePrivilege (htoken: kardinal; privrname: string; benennbar: boolean): boolean;
var
TP: token_privileges;
Dummy: Kardinal;
Beginnen
Tp.privilegeCount: = 1;
LookupprivileGeValue (NIL, PCHR (Privat), tp.privileges [0] .luid);
Wenn es biss haltbar ist
Tp.privileges [0] .attributes: = se_privilege_enabled
sonst tp.privileges [0] .attributes: = 0;
AdjateTokenPrivileges (htoken, false, tp, sizeof (tp), nil, dummy);
Ergebnis: = getLasterror = error_success;
Ende;
var
htoken: kardinal;
Beginnen
OpenProcessToken (getCurrentProcess, token_adjust_privileges, htoken);
Ergebnis: = EnablePrivilege (htoken, 'sedebugprivilege', true);
Nahe Handle (htoken);
Ende;
Wie man verwendet:
EnableDebugprivilege; // Berechtigungen erhöhen
Killtask ('xxxx.exe'); // Schließen Sie das Serviceprogramm.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------ ----------