-
Доброго времени суток. Подскажите пожалуйста если можно объединить сервис и приложение, которое он запускает в один ехе файл? Если можно, то как?
-
в поставке дельфи есть пример - приложение scktsrvr с исходниками.
а вопрос это вовсе не WinAPI, понимаю, все непонятное кажется сложным и одинаковым, а что может быть сложнее WinAPI... но тем не менее это не одно и тоже.
-
> defen © (11.07.10 05:01)
> объединить сервис и приложение, которое он запускает в один > ехе файл?
uses.
-- Regards, LVT.
-
уважаемые, это ветка "для начинающих" будте добры давать более развернутые ответы. не надо умничать!
-
> defen (12.07.2010 14:52:03) [3]
Наконец то - Ты не умничай, ты код давай.
-
> defen © (12.07.10 14:52) [3]
> уважаемые, это ветка "для начинающих"
Ну, начиналась-то она как WinAPI. И, видимо, для усвоения сложного задор тогда был.
> будте добры давать более развернутые ответы
А что непонятно?
-- Regards, LVT.
-
про поставку говорили что-то...
-
> defen © (13.07.10 01:31) [6] > > про поставку говорили что-то... >
Ну говорили. Искал? Или "не умничай, код давай"?
-
Какой код вам нужен? приложения или сервиса?
-
От код сервиса, запускающего мою прогу... Надо, чтобы сервис перезапускал приложение при его несанкционированном закрытии... uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,Registry,
WinSvc;
type
TService1 = class(TService)
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceContinue(Sender: TService; var Continued: Boolean);
procedure ServiceAfterInstall(Sender: TService);
private
public
function GetServiceController: TServiceController; override;
end;
var
Service1: TService1;
pi:PROCESS_INFORMATION;
si:STARTUPINFO;
implementation
const
SERVICE_CONFIG_FAILURE_ACTIONS = 2;
SC_ACTION_NONE = 0;
SC_ACTION_RESTART = 1;
SC_ACTION_REBOOT = 2;
SC_ACTION_RUN_COMMAND = 3;
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
type
SC_ACTION = record
_Type: DWORD;
Delay: DWORD;
end;
SERVICE_FAILURE_ACTIONS = record
dwResetPeriod: DWORD;
lpRebootMsg: LPTSTR;
lpCommand: LPTSTR;
cActions: DWORD;
lpsaActions: ^SC_ACTION;
end;
function ChangeServiceConfig2(hService: SC_HANDLE; dwInfoLevel: Cardinal;
lpInfo: Pointer): BOOL; stdcall; external advapi32 name 'ChangeServiceConfig2A';
function ExecCmd(const aCommand: String;const aShow, aWaitExit: Boolean): Boolean;
var
cmdLine,Path: String;
begin
ZeroMemory(@si,sizeof(si));
si.cb:=Sizeof(si);
si.dwFlags := STARTF_FORCEONFEEDBACK+STARTF_USESHOWWINDOW;
if aShow then si.wShowWindow := SW_SHOWNORMAL else si.wShowWindow := SW_SHOWMINNOACTIVE;
Path := ExtractFilePath(aCommand);
cmdLine := aCommand;
Result :=
CreateProcess( nil,
PChar(cmdline),
nil,
nil,
false,
0,
nil,
PChar(Path),
si,
pi );
if Result then
begin
if aWaitExit then WaitForSingleObject( pi.hProcess, infinite );
end;
end;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
ExecCmd('c:\1.exe',true,false);
AllowPause:=false;
end;
procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
var
RC: Integer;
begin
RC := WaitForSingleObject(pi.hProcess,0);
if RC<>WAIT_OBJECT_0 then TerminateProcess(pi.hProcess,0);
end;
procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
SuspendThread(pi.hThread);
end;
procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
ResumeThread(pi.hThread);
end;
procedure TService1.ServiceAfterInstall(Sender: TService);
const
ACTION_COUNT = 3;
var
scm, svc: SC_HANDLE;
sfa: SERVICE_FAILURE_ACTIONS;
sca: array[0..ACTION_COUNT - 1] of SC_ACTION;
hToken: THandle;
tkp: TOKEN_PRIVILEGES;
ret_len: Cardinal;
begin
scm := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if scm = 0 then RaiseLastWin32Error;
try
svc := OpenService(scm, PChar(Name), SERVICE_ALL_ACCESS);
if svc = 0 then RaiseLastWin32Error;
try
sfa.dwResetPeriod := 0;
sfa.lpRebootMsg := 'Сообщение перед перезагрузкой';
sfa.lpCommand := nil;
sfa.cActions := ACTION_COUNT;
sca[0]._Type := SC_ACTION_REBOOT;
sca[0].Delay := 0;
sca[1]._Type := SC_ACTION_REBOOT;
sca[1].Delay := 0;
sca[2]._Type := SC_ACTION_REBOOT;
sca[2].Delay := 0;
sfa.lpsaActions := @sca;
SE_SHUTDOWN_NAME
if not OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
RaiseLastWin32Error;
if not LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME,
tkp.Privileges[0].Luid) then
RaiseLastWin32Error;
tkp.PrivilegeCount := 1; tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if not AdjustTokenPrivileges(Cardinal(hToken), False, tkp, 0,
nil, ret_len) then
RaiseLastWin32Error;
if not ChangeServiceConfig2(svc, SERVICE_CONFIG_FAILURE_ACTIONS, @sfa) then
RaiseLastWin32Error;
finally
CloseServiceHandle(svc);
end;
finally
CloseServiceHandle(scm);
end;
end;
end.
-
> defen © (13.07.10 15:40) [9] > От код сервиса, запускающего мою прогу...
А теперь переносим функционал проги в OnExecute:
implementation
uses MyProg;
procedure TService1.Service1Execute(Sender: TService); begin .. end;
-- Regards, LVT.
-
> А теперь переносим функционал проги в OnExecute:
? :)
-
> ? :) и действительно. почитал код... как то я по другому себе объединение представлял.
но если понимать его так, то работа сервиса должна выполняться в OnExecute.
|