Windows 2000/XP и 2003 г. поддерживают что -то, что называется «Программы обслуживания».
(1) Вы можете запустить без входа в систему.
(2) иметь привилегии системы.
Когда в 2003 году я разрабатывал проект для компании в 2003 году, я написал загрузки курса и медиа-сервисы.
Запустите Delphi7, выберите файл меню-> Новый-> Другое ---> Приложение Сервиса. Структура.
(1) DisplayName: отображаемое имя службы
(2) Имя: имя службы.
Здесь мы изменем значение DisplayName на «Delphi Service Demo» и название «Delphiservice». расположено. Служба и текущий статус будут отображаться. Вернитесь в IDE Delphi7.
Наш план состоит в том, чтобы добавить главное окно для этой службы. функция
На самом деле, не думайте, что сервисная программа работает на рабочем столе Winlogon. Тик. Что мне делать?
Файл-> Новый-> Форма добавляет окно в службу, сохраняет блок как UNIT_FRMMAIN и устанавливает это окно для создания вручную.
UNIT UNIT_MAIN;
интерфейс
Использование
Windows, сообщения, Sysutils, классы, графика, управления, SVCMGR, Dialogs, unit_frmmain;
тип
Tdelphiservice = class (tservice)
Процедура ServiceContinue (отправитель: Tservice; var продолжил: логический);
Процедура ServiceExecute (отправитель: Tservice);
Процедура ServicePause (отправитель: tservice; var приостановлен: логический);
процедура ServiceShutDown (отправитель: Tservice);
Процедура ServiceStart (отправитель: Tservice; VAR начал: логический);
Процедура ServiceStop (отправитель: Tservice; var остановлен: логический);
Частный
{Частные объявления}
публичный
функция GetServiceController: TserviceController;
{Публичные объявления}
конец;
вар
Delphiservice: Tdelphiservice;
Frmmain: tfrmmain;
Выполнение
{$ R *.dfm}
Процедура ServiceController (CtrlCode: DWORD);
Начинать
Delphiservice.controller (ctrlcode);
конец;
Функция tdelphiservice.getServiceController: TserviceController;
Начинать
Результат: = ServiceController;
конец;
Процедура tdelphiservice.serviceContinue (отправитель: Tservice;
var продолжил: логическое);
Начинать
Пока не прекращается
Начинать
Сон (10);
ServiceThread.ProcessRequests (false);
конец;
конец;
Процедура tdelphiservice.serviceexecute (отправитель: tservice);
Начинать
Пока не прекращается
Начинать
Сон (10);
ServiceThread.ProcessRequests (false);
конец;
конец;
Процедура tdelphiservice.servicepause (отправитель: tservice;
VAR приостановлен: логический);
Начинать
Приостановил: = true;
конец;
Процедура tdelphiservice.serviceShutdown (отправитель: tservice);
Начинать
gbcanclose: = true;
Frmmain.free;
Статус: = csstopped;
ReportStatus ();
конец;
Процедура tdelphiservice.servicestart (отправитель: Tservice;
var начал: логическое);
Начинать
Начало: = true;
Svcmgr.application.createform (tfrmmain, frmmain);
gbcanclose: = false;
Frmmain.hide;
конец;
Процедура tdelphiservice.serviceStop (отправитель: Tservice;
Вар остановился: логический);
Начинать
Остановлен: = true;
gbcanclose: = true;
Frmmain.free;
конец;
конец.
Главное окно следующее:
UNIT UNIT_FRMMAIN;
интерфейс
Использование
Windows, сообщения, Sysutils, варианты, классы, Shellapi, графика, управления, формы,
Dialogs, extctrls, stdctrls;
констант
Wm_trayicon = wm_user + 1234;
тип
Tfrmmain = class (tform)
Таймер1: Ттимер;
Баттон1: Tbutton;
Процедура FormCreate (отправитель: Tobject);
Процедура FormClosequery (отправитель: tobject; var canclose: boolean);
процедура FormDestroy (отправитель: Tobject);
Процедура таймер1Timer (отправитель: tobject);
процедура Button1click (отправитель: tobject);
Частный
{Частные объявления}
Icondata: tnotifyicondata;
Процедура Addicontotray;
процедура DeliconFromTray;
процедура trayIConMessage (var msg: tmessage);
Процедура sysbuttonmsg (var msg: tmessage);
публичный
{Публичные объявления}
конец;
вар
Frmmain: tfrmmain;
GBCanclose: логический;
Выполнение
{$ R *.dfm}
Процедура tfrmmain.formcreate (отправитель: tobject);
Начинать
СТАРТИЛ: = fsstayontop;
SetWindowlong (Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
gbcanclose: = false;
Timer1.Interval: = 1000;
Timer1.enabled: = true;
конец;
Процедура tfrmmain.formclosequery (отправитель: tobject; var canclose: boolean);
Начинать
Canclose: = gbcanclose;
Если не пофу
Начинать
Скрывать;
конец;
конец;
Процедура tfrmmain.formDestroy (отправитель: tobject);
Начинать
Timer1.enabled: = false;
Deliconfromtray;
конец;
Процедура tfrmmain.addicontotray;
Начинать
Zeromemory (@icondata, sizeof (tnotifyicondata));
Icondata.cbsize: = sizeof (tnotifyicondata);
Icondata.wnd: = handle;
Icondata.uid: = 1;
Icondata.uflags: = nif_message или nif_icon или nif_tip;
Icondata.ucallbackmessage: = wm_trayicon;
Icondata.hicon: = application.icon.handle;
Icondata.sztip: = 'Delphi Service Demo Program';
Shell_notifyicon (nim_add, @icondata);
конец;
Процедура tfrmmain.deliconfromtray;
Начинать
Shell_notifyicon (nim_delete, @icondata);
конец;
Процедура tfrmmain.sysbuttonmsg (var msg: tmessage);
Начинать
if (msg.wparam = sc_close) или
(Msg.wparam = sc_minimize) затем скрыть
иначе унаследован;
конец;
Процедура tfrmmain.trayiconmessage (var msg: tmessage);
Начинать
if (msg.lparam = wm_lbuttondblclk), затем show ();
конец;
Процедура tfrmmain.timer1timer (отправитель: tobject);
Начинать
Addicontotray;
конец;
Процедура Sendhokkey; Stdcall;
вар
Hdesk_wl: hdesk;
Начинать
Hdesk_wl: = opendesktop ('winlogon', 0, false, desktop_journalplayback);
if (hdesk_wl <> 0) тогда
if (setThreadDesktop (hdesk_wl) = true) тогда
Postmessage (hwnd_broadcast, wm_hotkey, 0, makelong (mod_alt или mod_control, vk_delete));
конец;
Процедура tfrmmain.button1click (отправитель: tobject);
вар
dwthreadid: dword;
Начинать
CreateThread (Nil, 0, @sendhokkey, nil, 0, dwthreadid);
конец;
конец.
Пополнить:
(1) Для получения дополнительных программ демонстрационных программ, пожалуйста, посетите следующий URL: http://www.torry.net/pages.php?id=226, который содержит несколько кодов, которые демонстрируют, как управлять и управлять системными службами.
(2) Помните: Windows на самом деле имеет несколько рабочих столов. Он находится на рабочем столе.
(3) Существует также метод динамического переключения для взаимодействия между сервисной программой и рабочим столом.
единица обслуживания
интерфейс
функция initservicedesktop: логический;
Процедура DoneservicedEsktop;
Выполнение
использует Windows, Sysutils;
констант
DefaultWindowStation = 'winsta0';
Defauldesktop = 'default';
вар
Hwinstasave: Hwinsta;
HDESKSAVE: HDESK;
Hwinstauser: Hwinsta;
Hdeskuser: Hdesk;
функция initservicedesktop: логический;
вар
dwthreadid: dword;
Начинать
dwthreadid: = getCurrentThreadId;
// Обеспечение подключения к обслуживающей оконной станции и на рабочем столе и
// Сохранить их ручки.
hwinstasave: = GetProcessWindowStation;
hdesksave: = getThreaddesktop (dwthreadid);
hwinstauser: = openwindowstation (defaultwindowstation, false, maximum_allowed);
Если hwinstauser = 0, то тогда
Начинать
OutputDebugString (pchar ('OpenWindowStation не удастся' + syserrormessage (getLasterRor)));
Результат: = false;
Выход;
конец;
Если не SetProcessWindowStation (hwinstauser), тогда
Начинать
OutputDebugString ('setProcessWindowStation не удастся');
Результат: = false;
Выход;
конец;
hdeskuser: = opendesktop (defaultdesktop, 0, false, maximum_allowed);
Если hdeskuser = 0, тогда
Начинать
OutputDebugString ('Opendesktop не удастся');
SetProcessWindowStation (hwinstasave);
CloseWindowStation (Hwinstauser);
Результат: = false;
Выход;
конец;
Результат: = setThreadDesktop (hdeskuser);
Если не результаты, тогда
OutputDebugString (pchar ('setThreadDeskTop' + syserrormessage (getLasterRor)));
конец;
Процедура DoneservicedEsktop;
Начинать
// восстановить оконную станцию и рабочий стол.
SetThreadDesktop (HdesKsave);
SetProcessWindowStation (hwinstasave);
Если hwinstauser <> 0, то тогда
CloseWindowStation (Hwinstauser);
Если hdeskuser <> 0, то тогда
Закрытый
конец;
Инициализация
Initservicedesktop;
Завершение
Doneservicedesktop;
конец.
Для получения более подробного демонстрационного кода, пожалуйста, см.
(4) Как добавить описания услуг о том, как установить службу. Мы только сейчас расположены в HKEY_LOCAL_MACHINE/SYSTER/CONTROLSET001. следует:
Устройство Winsvcex;
интерфейс
использует Windows, WinSVC;
констант
//
// уровни информации конфигурации службы
//
Service_config_description = 1;
Service_config_failure_actions = 2;
//
// Имя импортируемых функций DLL
//
Advapidll = 'advapi32.dll';
тип
//
// Служба описания строки
//
Pserviceedescriptiona = ^tserviceedescriptiona;
Pserviceedescriptionw = ^tservicedescriptionw;
Pserviceedescription = pserviceedescriptiona;
{$ Externalsym _service_descriptiona}
_Service_descriptiona = record
LPDescription: Pansichar;
конец;
{$ Externalsym _service_descriptionw}
_Service_descriptionw = record
LPDescription: PWIDECHAR;
конец;
{$ 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 = tserviceedescriptiona;
//
// Действия, чтобы взять на себя неудачу услуг
//
{$ 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 = запись
atype: sc_action_type;
Задержка: DWORD;
конец;
{$ Externalsym sc_action}
Sc_action = _sc_action;
TserviceAction = _SC_Action;
PservicefailureActionsa = ^tservicefailureActionsa;
PservicefailureActionsw = ^tservicefailureActionsw;
PservicefailureActions = pservicefailureActionsa;
{$ Externalsym _service_failure_actionsa}
_Service_failure_actionsa = запись
DWRESETPERIOD: DWORD;
lprebootmsg: lpstr;
LPCommand: LPSTR;
Cactions: dword;
lpsaCations: ^sc_action;
конец;
{$ Externalsym _service_failure_actionsw}
_Service_failure_actionsw = запись
DWRESETPERIOD: DWORD;
lprebootmsg: lpwstr;
LPCommand: LPWSTR;
Cactions: dword;
lpsaCations: ^sc_action;
конец;
{$ 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;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////
// Прототипы функций API
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////
TqueryServiceConfig2 = функция (hservice: sc_handle; dwinfolevel: dword; lpbuffer: pointer;
CBBUFSIZE: DWORD;
Tchangeserviceconfig2 = function (hservice: sc_handle; dwinfolevel: dword; lpinfo: pointer): bool;
вар
Hdll: Тандл;
Libloaded: логический;
вар
Osversioninfo: Tosversioninfo;
{$ Externalsym QueryServiceConfig2a}
QueryServiceConfig2a: TqueryServiceConfig2;
{$ Externalsym QueryServiceConfig2w}
QueryServiceConfig2w: TqueryServiceConfig2;
{$ Externalsym QueryServiceConfig2}
QueryServiceConfig2: TqueryServiceConfig2;
{$ Externalsym insomeerviceconfig2a}
InmedingErviceConfig2a: tchangeserviceConfig2;
{$ Externalsym insomeerviceconfig2w}
IndisterServiceConfig2W: tchangeserviceConfig2;
{$ Externalsym insomeerviceconfig2}
ChangeserviceConfig2: tchangeserviceConfig2;
Выполнение
Инициализация
Osversioninfo.dwosverioninfosize: = sizeof (osversioninfo);
GetVersionex (osversioninfo);
if (osversioninfo.dwplatformid = ver_platform_win32_nt) и (osversioninfo.dwmajorversion> = 5) тогда
Начинать
Если hdll = 0, тогда
Начинать
hdll: = getModuleHandle (Advapidll);
Libloaded: = false;
Если hdll = 0, тогда
Начинать
hdll: = LoadLibrary (AdvapIdll);
Libloaded: = true;
конец;
конец;
Если hdll <> 0, то
Начинать
@QueryServiceConfig2a: = getProcadDress (hdll, 'QueryServiceConfig2a');
@QueryServiceConfig2w: = getProcadDress (hdll, 'QueryServiceConfig2w');
@QueryServiceConfig2: = @QueryServiceConfig2a;
@Changesserviceconfig2a: = getProcadDress (hdll, 'insomeerviceConfig2a');
@Changesserviceconfig2w: = getProcadDress (hdll, 'insomeerviceConfig2w');
@Changesserviceconfig2: = @changesserviceconfig2a;
конец;
конец
еще
Начинать
@QueryServiceConfig2a: = nil;
@QueryServiceConfig2w: = nil;
@QueryServiceConfig2: = nil;
@Changesserviceconfig2a: = nil;
@Changeserviceconfig2w: = nil;
@Changesserviceconfig2: = nil;
конец;
Завершение
if (hdll <> 0) и libloaded
Фрилибрика (HDLL);
конец.
подразделение Винтрингис;
интерфейс
Использование
Windows, Winsvc, Winsvcex;
Функциональная установка (const strserviceName, strdisplayName, strdescription, strfilename: string): boolean;
// например: installService («Имя службы», «Отображение имя», «Описание информации», «Файл службы»);
Процедура UninstallService (StrserviceName: String);
Выполнение
Функция strlcopy (dest: pchar; const source: pchar; maxlen: cardinal): pchar;
Асм
Push edi
Push esi
Толк Эбс
MOV ESI, EAX
Mov Edi, Edx
MOV EBX, ECX
XOR AL, AL
Тест 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
И ECX, 3
Rep Movsb
Стосб
MOV EAX, EDX
Pop Ebx
Поп -эс
Поп -эди
конец;
функция strpchar (dest: pchar; const source: string): pchar;
Начинать
Результат: = strlCopy (dest, pchar (источник), длина (источник));
конец;
Функциональная установка (const strserviceName, strdisplayName, strdescription, strfilename: string): boolean;
вар
// ss: tservicestatus;
// pStemp: pchar;
HSCM, HSCS: Thandle;
Srvdesc: PserviceedEscription;
Desc: String;
// srvtype: dword;
lpserviceargvectors: pchar;
Начинать
Результат: = false;
// pStemp: = nil;
// srvtype: = service_win32_own_process и service_interactive_process;
HSCM: = opensCmanager (Nil, Nil, SC_MANAGER_ALL_ACCESS); // Подключить базу данных службы
Если hscm = 0, то exit; // Messagebox (hhandle, pchar (syserrormessage (getlasterror)), «менеджер программы службы», MB_ICOnerror+MB_TOP);
HSCS: = CreateService (// Создать функцию службы
HSCM, // Руководство управления управлением услугами
Pchar (strservicename), // имя обслуживания
Pchar (strdisplayName), // отображается имя службы
Service_all_access, // права доступа
Service_win32_own_process или service_interactive_process, // service type service_win32_share_process
Service_auto_start, // тип запуска
Service_error_ignore, // Тип управления ошибкой
Pchar (strfilename), // программа обслуживания
ноль, // название службы группы
ноль, // идентификатор группы
ноль, // зависимые услуги
ноль, // запустить учетную запись службы
nil);
Если hscs = 0, то выход; // Messagebox (hhandle, pchar (syserrormessage (getlasterror)), pchar (application.title), mb_iconerror+mb_topest);
Если назначено (изменяет erviceConfig2), то
Начинать
desc: = copy (strdescription, 1,1024);
GetMem (srvdesc, sizeof (tservicedescription));
GetMem (srvdesc^.lpdescription, длина (desc) + 1);
пытаться
Strpcopy (srvdesc^.lpdescription, desc);
ChangeserviceConfig2 (HSCS, service_config_description, srvdesc);
Окончательно
Freemem (srvdesc^.lpdescription);
Freemem (srvdesc);
конец;
конец;
lpserviceargvectors: = nil;
Если не запускает сохранение (HSCS, 0, LPServiceArgVectors), то // запустить сервис
Выход;
Заключение ServiceHandle (HSCS);
Результат: = true;
конец;
Процедура UninstallService (StrserviceName: String);
вар
Scmanager: sc_handle;
Служба: SC_HANDLE;
Статус: TSERVICESTATUS;
Начинать
Scmanager: = openscmanager (nil, nil, sc_manager_all_access);
Если scmanager = 0, то выход;
пытаться
Сервис: = OpenService (Scmanager, Pchar (StrservicEname), Service_all_Access);
Контрольная служба (Service, service_control_stop, status);
DeletEservice (обслуживание);
CloseServiceHandle (обслуживание);
Окончательно
CloseServiceHandle (Scmanager);
конец;
конец;
конец.
(5) Как жестоко закрепить сервисную программу и реализовать функцию нашего предыдущего «NT Toolbox»?
использует TLHELP32;
Функция Killtask (ExefilEname: String): Integer;
констант
Process_terminate = $ 0001;
вар
Continuelup: Bool;
Fsnapshothandle: Thandle;
FProcessEntry32: tProcessEntry32;
Начинать
Результаты: = 0;
Fsnapshothandle: = createtoolhelp32snapshot (th32cs_snapcess, 0);
FprocessEntry32.dwsize: = sizeof (fProcessEntry32);
Continuelup: = Process32first (fsnapshothandle, fprocessentry32);
в то время как целое число (Continuelupoop) <> 0
Начинать
if ((uppercare (ExtractFilEname (fprocessEntry32.szexefile)) =
Вершинный (EXEFILENAME)) или (верхний заглавный (fProcessEntry32.szexefile) =
Верхний (EXEFILENAME)) тогда
Результат: = Integer (TerminateProcess (
OpenProcess (Process_Terminate,
Bool (0),
Fprocessentry32.th32pocessid),
0));
Continueluloop: = Process32next (fsnapshothandle, fprocessentry32);
конец;
Крупный отрыв (FSNAPSHOTHANDLE);
конец;
Тем не менее, для программы обслуживания она будет вызвать «Доступ, отказанный».
Функция EnableBugPrivilege: Boolean;
функция enablePrivilege (htoken: cardinal; privname: String; Benable: Boolean): Boolean;
вар
TP: token_privileges;
Манекен: кардинал;
Начинать
Tp.privilegecount: = 1;
Lookupprivilegevalue (ноль, pchar (privname), tp.privileges [0] .luid);
Если Бенабл, тогда
Tp.privileges [0] .attributes: = se_privilege_enabled
else tp.privileges [0] .atributes: = 0;
AdvitationTokenPrivileges (htoken, false, tp, sizeof (tp), ноль, манекен);
Результат: = getLasterRor = error_success;
конец;
вар
Htoken: кардинал;
Начинать
OpenProcessToken (getCurrentProcess, token_adjust_privileges, htoken);
Результат: = enablePrivilege (htoken, 'sedebugprivilege', true);
Крупный руск (HTOKEN);
конец;
Как использовать:
EnableBugPrivilege; // повышать разрешения
Killtask ('xxxx.exe'); // Закрыть программу обслуживания.
------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------ ------ -----------