Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.04.2012, 11:18   #1
varelik
Форумчанин
 
Регистрация: 21.08.2009
Сообщений: 140
По умолчанию Проблема с таймером в службе

Здравствуйте, помогите разобраться..

Начал писать службу, использовав ServiceApplication.
На ее "форму" поместил Timer.
В Onclick таймера выдаются сообщения при определенных действиях.

Проблема в том что таймер перестает функционировать после регистрации службы в системе, т.е.: пуск-выполнить-"путь к файлу" /install, появляется сообщение "служба установлена" - жму ОК и таймер глохнет.
До нажатия ОК-работает.


Посоветуйте или помогите кодом...

Делал так:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
  ExtCtrls;

type
  TService1 = class(TService)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure ServiceCreate(Sender: TObject);
    procedure ServiceExecute(Sender: TService);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServicePause(Sender: TService; var Paused: Boolean);
    procedure ServiceContinue(Sender: TService; var Continued: Boolean);
  private
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  Service1: TService1;
  s:string; f1:textfile;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TService1.Timer1Timer(Sender: TObject);
begin

try

if getasynckeystate(57)<>0 then begin
 s:='9 ';
  AssignFile(f1,'C:\11.txt');
   append(f1);
  write(f1,s);
 closefile(f1);
end;

 except
 exit;
 end;

end;

procedure TService1.ServiceCreate(Sender: TObject);
begin
try
 if (not FileExists('C:\11.txt')) then  begin
   AssignFile(f1,'C:\11.txt');
    rewrite(f1);
   closefile(f1);
   end;
  except
 exit
end;
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
while not terminated do
begin
servicethread.ProcessRequests(true);
end;
end;


procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
timer1.Enabled:=false;
stopped:=true;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
timer1.Interval:=2000;
 timer1.Enabled:=true;
started:=true;
end;


procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
Paused:=true;
end;

procedure TService1.ServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
Continued:=true;
end;

end.

Последний раз редактировалось varelik; 16.04.2012 в 11:35.
varelik вне форума Ответить с цитированием
Старый 16.04.2012, 11:53   #2
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

а кто будет принимать сообщение WM_TIMER? Служба? Не, она не умеет, ну нет у нее оконных элементов.
Решений два:
1 - корявое: создайте форму, подвяжите ее к службе, вызывайте конструктор и работайте на ней. Там же и таймер разместите.
2 - нормальное: создайте в конструкторе службы поток с бесконечным циклом, в котором через нужный вам интервал времени будет что-то делаться. Т.е. эмуляция таймера.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 16.04.2012, 12:51   #3
varelik
Форумчанин
 
Регистрация: 21.08.2009
Сообщений: 140
По умолчанию

хорошо, делаю через поток, убрал таймер, подредактировал код,
не работает,
такое впечатление что tnewthread1.execute не срабатывает.
поправьте пожалуйста

Код:
...
  type tnewthread1=class(tthread)
  protected
   procedure execute;override;
  end;
...
var
  Service1: TService1;
  s:string; f1:textfile;
  d:integer;
  newthread1: tnewthread1;
...

procedure TService1.ServiceCreate(Sender: TObject);
begin
d:=0;
try
 if (not FileExists('C:\11.txt')) then  begin
   AssignFile(f1,'C:\11.txt');
    rewrite(f1);
   closefile(f1);
   end;
  except
 exit
end;
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
newthread1.execute;
while not terminated do
begin
servicethread.ProcessRequests(true);
end;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
newthread1.Terminate;
stopped:=true;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
newthread1:=  tnewthread1.Create(true);
newthread1.Priority:=tpnormal;
newthread1.Resume;
started:=true;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
newthread1.Suspend;
Paused:=true;
end;

procedure TService1.ServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
newthread1.Resume;
Continued:=true;
end;

procedure tnewthread1.execute;
begin
showmessage('poexali');
while d<>1 do begin
sleep(20);
  if getasynckeystate(57)<>0 then begin
 s:='9 ';
  AssignFile(f1,'C:\11.txt');
   append(f1);
  write(f1,s);
 closefile(f1);
end;
end;
end;

end.
varelik вне форума Ответить с цитированием
Старый 16.04.2012, 14:24   #4
varelik
Форумчанин
 
Регистрация: 21.08.2009
Сообщений: 140
По умолчанию

указаный код заработал после установки свойства службы interactive=true, но насколько это правильно?
varelik вне форума Ответить с цитированием
Старый 16.04.2012, 14:59   #5
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Это что за код?! Практическая полезность его равна нулю.. не понятно, но поправлю.
Код:
procedure TService1.ServiceCreate(Sender: TObject);
begin
d:=0;
try
 if (not FileExists('C:\11.txt')) then  begin
   AssignFile(f1,'C:\11.txt');
    rewrite(f1);
   closefile(f1);
   end;
  except
 exit
end;
end;
Правильно так:
Код:
procedure TService1.ServiceCreate(Sender: TObject);
begin
  try
    AssignFile(f1,'C:\11.txt');
    if (not FileExists('C:\11.txt')) then rewrite(f1) else append(f1);
  finally
    closefile(f1);
  end;
end;
И бесконечный цикл можно сделать без переменной d:
Код:
procedure tnewthread1.execute;
begin
showmessage('poexali');
while true do begin
...
Свойство Interactive дает возможность обрабатывать сообщения от системы, ведь вызов ShowMessage() не просто так тебе штампует окошки со строчками)
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 16.04.2012, 15:03   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

На w7 интерактивности вообще нет.

Пишите мультимедийный класс таймера, что довольно легко(в своей теме как-то выкладывал свою реализацию таймера, именно для сервисов, ищите сами).

Сервис вырубается SCM(Service Control Manager), по-скольку ваш сервис не сообщает SCM свой статус каждые WaitHint.

Последний раз редактировалось Человек_Борща; 16.04.2012 в 15:08.
Человек_Борща вне форума Ответить с цитированием
Старый 16.04.2012, 15:45   #7
varelik
Форумчанин
 
Регистрация: 21.08.2009
Сообщений: 140
По умолчанию

3D Hunter, смысл в коде есть.
в таймере (либо в потоке) планировалось чтото типа клавиатурного шпиона сделать (с сохранением нажатых клавиш в c:\11.txt например). Решил просто попробовать реализовать как сервис.
В результате: если interactive=true, все работает и через таймер и через поток.
если interactive=false - ни потоки, ни таймеры не помогают.

всем спасибо за внимание!
varelik вне форума Ответить с цитированием
Старый 16.04.2012, 17:53   #8
varelik
Форумчанин
 
Регистрация: 21.08.2009
Сообщений: 140
По умолчанию

Человек_Борща, про мультимедийный таймер посмотрю обязательно.

вопрос ко всем:
но если не использовать таймер вобще и делать через цикл в потоке (при interactive=false):
почему не работает?
varelik вне форума Ответить с цитированием
Старый 16.04.2012, 20:43   #9
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Читаем MSDN:
Цитата:
Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx
И вообще данная функция проверяет статус клавиши по виртуальному коду - нажата или отжата.
И там не все так просто: побитовая проверка требуется:
Цитата:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 16.04.2012, 21:15   #10
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
Решений два:
allocatehwnd(), вот и окно.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с сис таймером Lauri Общие вопросы Delphi 7 08.11.2012 22:26
Нет доступа к службе установщика Windows Installer fenyfe Помощь студентам 0 19.12.2011 19:04
Проблема с таймером обратного отсчета nursak Помощь студентам 10 05.06.2011 17:58
проблема с таймером javascript storm296 JavaScript, Ajax 1 03.08.2010 15:38
ошибка в службе Windows Installer Nsrvitaliy Windows 17 19.01.2010 14:21