![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ув. мастера, помогите разобраться с сервисом - жрет 100% процессо [D6, Win2k, WinXP]
AversFm © (2006-02-13 17:28:00)Ув. мастера, помогите разобраться с сервисом - жрет 100% процессора.
Написал сервис, который по таймеру выполняет некоторое действие (в данном случае - Beep). Но после инсталляции он на себя тянет почти все процессорное время!
Подскажите, что не так.
И еще вопрос вдогонку: как из сервиса выполнить команду, например net time? WinExec не проходит.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
ExtCtrls;
type
TService1 = class(TService)
Timer1: TTimer;
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceAfterInstall(Sender: TService);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure Timer1Timer(Sender: TObject);
procedure ServiceExecute(Sender: TService);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
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
Timer1.Interval:=5000;
Timer1.Enabled:=true;
end;
procedure TService1.ServiceAfterInstall(Sender: TService);
begin
DoStart;
end;
procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
Timer1.Enabled:=false;
end;
procedure TService1.Timer1Timer(Sender: TObject);
begin
Beep;
end;
procedure TService1.ServiceExecute(Sender: TService);
begin
while not Terminated do
begin
ServiceThread.ProcessRequests(True);
ReportStatus;
// Sleep(500);
end;
end;
end.
AversFm (2006-02-15 22:07:00) [1]
> Digitman © (15.02.06 08:20) [18]
> Как запускаешь-то ? Как обычное приложение что ли ?
> Запуск сервиса должен осуществляться под управлением Service
> Control Manager'а.
Уже разобрался. Если при выполнении службы возникает ошибка, то в этом случае система ее останавливает (хотя с такой вот странной формулировкой).
Digitman (2006-02-15 08:20:00) [2]
> при запуске службы система через 2-3 сек. ее автоматом останавливает
Как запускаешь-то ? Как обычное приложение что ли ?
Запуск сервиса должен осуществляться под управлением Service Control Manager'а.
AversFm (2006-02-14 23:53:00) [3]
> Digitman ©
Большое спасибо.
> Rouse_ ©
Огромное спасибо. Все отлично работает, но не в теле службы. Инсталяция проходит успешно, но при запуске службы система через 2-3 сек. ее автоматом останавливает: говорит что этой службе нечего делать. Попробую еще поиграть с задержкой...
Rouse_ (2006-02-14 23:07:00) [4]Аналог на дельфи:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
PTIME_OF_DAY_INFO = ^TIME_OF_DAY_INFO;
TIME_OF_DAY_INFO = record
tod_elapsedt : DWORD;
tod_msecs : DWORD;
tod_hours : DWORD;
tod_mins : DWORD;
tod_secs : DWORD;
tod_hunds : DWORD;
tod_timezone : Longint;
tod_tinterval: DWORD;
tod_day : DWORD;
tod_month : DWORD;
tod_year : DWORD;
tod_weekday : DWORD;
end;
function NetRemoteTOD(Server: PWChar; var pBuffer: PTIME_OF_DAY_INFO): DWORD;
stdcall; external 'NETAPI32.DLL';
function NetApiBufferFree(pBuffer: Pointer): DWORD;
stdcall; external 'NETAPI32.DLL';
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
TOD: PTIME_OF_DAY_INFO;
begin
if NetRemoteTOD('\\192.168.2.108', TOD) = 0 then
try
with TOD^ do
ShowMessage(Format('Data %d %d %d Time %d:%d:%d',
[tod_day, tod_month, tod_year, tod_hours - (tod_timezone div 60),
tod_mins, tod_secs]));
finally
NetApiBufferFree(TOD);
end
else
RaiseLastOSError;
end;
end.
BiN (2006-02-14 09:33:00) [5]
> AversFm (13.02.06 20:19) [13]
>
> Ув. мастера, помогите разобраться. В крайнем случае решением
> может быть прямая синхронизация времени с другим компьютером
> минуя команду net time (если таковое вообще возможно).
Example Code
The following code sample demonstrates how to retrieve and print the current date and time with a call to the NetRemoteTODfunction. To do this, the sample uses the TIME_OF_DAY_INFO structure. Finally, the sample frees the memory allocated for the information buffer.
#ifndef UNICODE
#define UNICODE
#endif
#include
#include
#include
int wmain(int argc, wchar_t *argv[])
{
LPTIME_OF_DAY_INFO pBuf = NULL;
NET_API_STATUS nStatus;
LPTSTR pszServerName = NULL;
if (argc > 2)
{
fwprintf(stderr, L"Usage: %s [\\\\ServerName]\n", argv[0]);
exit(1);
}
// The server is not the default local computer.
//
if (argc == 2)
pszServerName = argv[1];
//
// Call the NetRemoteTOD function.
//
nStatus = NetRemoteTOD(pszServerName,
(LPBYTE *)&pBuf);
//
// If the function succeeds, display the current date and time.
//
if (nStatus == NERR_Success)
{
if (pBuf != NULL)
{
fprintf(stderr, "\nThe current date is: %d/%d/%d\n",
pBuf->tod_month, pBuf->tod_day, pBuf->tod_year);
fprintf(stderr, "The current time is: %d:%d:%d\n",
pBuf->tod_hours, pBuf->tod_mins, pBuf->tod_secs);
}
}
//
// Otherwise, display a system error.
else
fprintf(stderr, "A system error has occurred: %d\n", nStatus);
//
// Free the allocated buffer.
//
if (pBuf != NULL)
NetApiBufferFree(pBuf);
return 0;
}
© MSDN
Digitman (2006-02-14 09:16:00) [6]
> В крайнем случае решением может быть прямая синхронизация
> времени с другим компьютером минуя команду net time (если
> таковое вообще возможно).
см. TIdDayTime, TIdDayTimeUDP
AversFm (2006-02-13 20:19:00) [7]Бараны попятились, но не сдались :)
Для того, чтобы использовать WinExec нужно установить свойство Interactive=true. Теперь команду net time запустить можно, но она не проходит: "отказано в доступе". А если задать учетную запись (не LocalSystem), то Interactive становиться false и команда не выполняется.
Ув. мастера, помогите разобраться. В крайнем случае решением может быть прямая синхронизация времени с другим компьютером минуя команду net time (если таковое вообще возможно).
AversFm (2006-02-13 19:21:00) [8]И снова я о своих баранах...
Как из сервиса выполнить команду, например net time? WinExec не проходит.
Для пробы пытался запустить cmd.exe - результат тот же.
atruhin (2006-02-13 18:13:00) [9]>>Это частный пример. А если у меня по таймеру нужно выполнить несколько долгих команд
Естественно это намек на то, что в сервисе создается поток и все действия выполняются в этом потоке. Несколько комманд - создавай доп. потоки, смотри ожидаемые таймера, синхронизацию потоков.
Почитай о службе времени Windows.
AversFm (2006-02-13 18:00:00) [10]
> Игорь Шевченко © (13.02.06 17:44) [6]
>
> Правда непонятно, зачем такой сервис нужен.
Нужен для синхронизации информации на разных машинах. А почему именно сервис, так чтобы синхронизация проходила даже без входа пользователя в систему и в том случае, если используется оболочка отличная от Explorera
AversFm (2006-02-13 17:55:00) [11]
> kaZaNoVa © (13.02.06 17:46) [8]
> AversFm (13.02.06 17:44) [7]
> а сервис от кого запущен? есть права на смену времени?)
Запущен от LocalSystem. Но текущий пользователь имеет права админа.
Кстати пробовал прописать пользователя, но постоянно выдает ошибку. Или я что-то путаю:
procedure TService1.ServiceBeforeInstall(Sender: TService);
begin
Service1.ServiceStartName:='MyUser';
Service1.Password:='MyPassword';
end;
kaZaNoVa (2006-02-13 17:46:00) [12]AversFm (13.02.06 17:44) [7]
а сервис от кого запущен? есть права на смену времени?)
AversFm (2006-02-13 17:44:00) [13]
> kaZaNoVa © (13.02.06 17:36) [4]
> AversFm (13.02.06 17:28)
> WinExec не проходит.
> почему?
Не могу сказать, но если я в сервисе делаю синхронизацию времени, то она не проходит. И нормально выполняется из сомандной строки.
procedure TService1.Timer1Timer(Sender: TObject);
begin
WinExec('net time \\192.168.0.1 /SET /yes',SW_HIDE);
end;
Игорь Шевченко (2006-02-13 17:44:00) [14]
> Написал сервис, который по таймеру выполняет некоторое действие
RTFM WaitableTimers
Правда непонятно, зачем такой сервис нужен.
AversFm (2006-02-13 17:37:00) [15]
> atruhin © (13.02.06 17:34) [1]
> Попробуй так:
> while not Terminated do
> begin
> Sleep(5000);
> beep;
> end;
> и будет счастье.
Это частный пример. А если у меня по таймеру нужно выполнить несколько долгих команд, то такой вариант будет корректен?
kaZaNoVa (2006-02-13 17:36:00) [16]AversFm (13.02.06 17:28)
WinExec не проходит.
почему?
kaZaNoVa (2006-02-13 17:35:00) [17]sleep (1) обычно ...
AversFm (2006-02-13 17:35:00) [18]Методом перебора нашел ответ на первый вопрос. Убрал
DoStart;
изAfterInstallи все наладилось. Почему - непонятно.
Второй вопрос по запуску из сервиса остается открытым.
atruhin (2006-02-13 17:34:00) [19]Попробуй так:
while not Terminated do
begin
Sleep(5000);
beep;
end;
и будет счастье.