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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2011, 08:54   #1
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
Смущение Создание службы

Привет, программисты.. Есть вопрос. Написал прогу по конвертации определенных данных. Все хорошо и быстро работает, но есть необходимость выполнять программу в качестве службы. И вот тут возникли проблемы. Создал проект службы, впихнул код в OnExecute, откомпилил, проинсталил, но винда пишет, что моя служба остановлена, т.к. ей нечего делать. В OnStart пихал код - но тот же результат. Кто знает опишите плиз подробней правильный порядок действий (желательно с кодом), чтоб служба выполняла мой код раз в минуту и не останавливалась. Я в инете, конечно пороюсь еще, но если можете - хелп .
По ракетам и хоккею - Россияне всех сильней!

Последний раз редактировалось Ky3Heu,; 22.11.2011 в 08:58.
Ky3Heu, вне форума Ответить с цитированием
Старый 22.11.2011, 09:06   #2
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

не очень хорошая идея выполнять код в основном потоке службы. В событии OnStart создавайте поток, который и будет заниматься выполнением всей работы. А служба ваша останавливается менеджером служб из-за того, что SCM вовремя не получил сообщенияо состоянии службы скорей всего.
Формальный код таков:
Код:
type
  TMyThr = class(TThread)
  protected
    ...
  public
    ...
  end;

...

var
  gThr:TMyThr;

procedure Service1Start();
begin
  gThr:=TMyThr.Create(<ваши параметры конструктора>);
end;

...

procedure Service1Stop();
begin
  //если FreeOnTerminate=false
  gThr.Terminate;
  gThr.WaitFor;
  //в общем случае
  FreeAndNil(gThr);
end;
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 22.11.2011, 09:31   #3
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
По умолчанию

Не совсем понял
Код:
gThr:=TMyThr.Create(<ваши параметры конструктора>);
но попробую разобраться.. И куда свой код впихивать???
По ракетам и хоккею - Россияне всех сильней!
Ky3Heu, вне форума Ответить с цитированием
Старый 22.11.2011, 09:36   #4
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Вы работали с потоками? Если нет, то изучаем основы многопоточных приложений:
http://forum.vingrad.ru/forum/s/a0e9...y480344/0.html
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 22.11.2011, 11:01   #5
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
По умолчанию

Спасибо за издевательство, конечно.. Но мне сейчас пример работающий нужен.. За ссылку отдельное спасибо.. Я от туда все равно ничего не понял...
По ракетам и хоккею - Россияне всех сильней!
Ky3Heu, вне форума Ответить с цитированием
Старый 22.11.2011, 11:06   #6
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

http://www.delphikingdom.ru/asp/view...catalogid=1348

Цитата:
есть необходимость выполнять программу в качестве службы
И какая я же это необходимость?

Цитата:
Я от туда все равно ничего не понял
Это как бы говорит, что задача тебе не по зубам. Опыта наберись, а потом к ней вернись.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 22.11.2011, 11:42   #7
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
По умолчанию

Необходимость есть. Прога должна на серваке вертеться и раз в минуту передавать данные, а наш админ любит серваки в логофе держать. Так что только служба. А по зубам или не по зубам - решать в данном случае мне.. Я сюда обратился за помощью, а не для обсуждения личного опыта в программировании. Ссылку обязательно гляну.
По ракетам и хоккею - Россияне всех сильней!
Ky3Heu, вне форума Ответить с цитированием
Старый 22.11.2011, 12:59   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Выход из ситуации вам дали 2 сообщением.

Создаёте сервис, а сервис создаёт поток и управляет им.
Сам сервис ничего не делает.
На основе потока(tThread), пишите свой класс/код, и пускай себе работает себе.
К тому же сервис каждые WaitHint обязан сообщать SCM свой статус, если он этого не делает, значит сервис не работает и SCM прибьёт его.
на SCM я посылал сообщения при помощи мультимедийного таймера.
Предварительно проверяя поток(жив, мёртв, на паузе) и в зависимости от этого, манипулировал сервисом и его статусом.


Вот и всё в принципе.
Человек_Борща вне форума Ответить с цитированием
Старый 22.11.2011, 14:25   #9
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
По умолчанию

Вот сокращенный код приложения (весь не влазил). Напишите плиз где я лажанул и как исправить. Служба должна отрабатывать каждые 60 сек. Я еще не понимаю всех этих процессов, а запустить ПО необходимо очень срочно!!!!! Так что тупо нет времени изучать что из чего...
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
   Generics.Collections, ShellAPI, IniFiles, DB, ADODB, xmldom, XMLIntf,
  msxmldom, XMLDoc, ExtCtrls;

type

  TState = (stNormal, stWarning, stError);

  TCodes = TDictionary<string, Double>;

  TConverter = class(TService)
    Data: TADOQuery;
    ADOConnection: TADOConnection;
    XMLInput: TXMLDocument;
    DataCodePAR: TIntegerField;
    DataPValue: TFloatField;
    DataCOLUMN1: TIntegerField;
    DataCOLUMN2: TIntegerField;
    Timer1: TTimer;

    procedure Run;
    procedure Log (State :TState; Msg :string);
    procedure ExportToXML;
    procedure ConvertDateTime;
    procedure Connect;
    procedure Timer1Timer(Sender: TObject);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);

  private
  {}
  public

    function GetServiceController: TServiceController; override;

  end;
  //-------------------------------------

  TMyThr = class(TThread)
  protected

   procedure Execute; override;

  public
    {}
  end;
//-----------------------------------------
var
  Converter: TConverter;

  gThr:TMyThr;

  Ini   :TIniFile;
  Codes :TCodes;
  FDate :string;

implementation

{$R *.DFM}

function WindowsCopyFile (FromFile, ToDir :string) : Boolean;
var F : TShFileOpStruct;
begin
 //операторы
end;

//------------------------------------
procedure TmyThr.execute;
begin
  Codes := TCodes.Create;
  Ini   := TIniFile.Create(GetCurrentDir + '\config.ini');

  With Converter do
  begin
  Connect;
  XMLInput.FileName := GetCurrentDir + '\data.xml';
  XMLInput.Active   := True;
  Timer1.Enabled := True;
  end; //With TConverter do

end;

procedure TConverter.Log (State :TState; Msg :string);
var st :string;
begin
 //операторы
  end;
end;

// Запись данных в XML-файл
procedure TConverter.ExportToXML;
var Node, NodeID :IXMLNode;
    Value :Double;
begin
//операторы
  Log(stNormal, 'Завершение процесса экспорта в XML');
  data.Close;
  WindowsCopyFile(GetCurrentDir+'\outf.xml',GetCurrentDir+'\ForSurgut.xml');
end;

// Конвертация даты/времени
procedure TConverter.ConvertDateTime;
var d, t, r :string;
begin
  //.......
  end;
end;

// Установка соединения
procedure TConverter.Connect;
begin
  //операторы
end;

// Основная процедура обработки данных
procedure Tconverter.Run;
var
  InCode  :string; // 
  ExCode  :string; // 
  Params  :TStringList;
  Values  :TStringList;

  i, code :Integer;
  value   :Double;

  function ExtractParams(str :string) :string;
  var i :Integer;
  begin
    i := 1;
    while str[i] <> '=' do Inc(i);
    Delete(str, i-1, Length(str));
    Result := str;
  end;

  function ExtractValue(str :string) :string;
  var i :Integer;
  begin
    i := 1;
    while str[i] <> '=' do Inc(i);
    Delete(str, 1, i+1);
    Result := str;
  end;

begin
  Params  := TStringList.Create;
  Values  := TStringList.Create;

  Log(stNormal, 'Начало обработки данных');

  try
  Params.LoadFromFile(GetCurrentDir+'\codes.txt');
  Values.LoadFromFile(GetCurrentDir+'\codes.txt');
//... и т.д.
    Log(stNormal, 'Завершение обработки данных');
    ExportToXML;

  except
    on E : Exception do begin
      Params.Free;
      Values.Free;
      Data.Close;
      Log(stError, 'Процесс завершился с ошибкой: ' + E.Message);
    end;
  end;
end;

//------------------------------------

procedure TConverter.ServiceStart(Sender: TService; var Started: Boolean);
begin
gThr.Create(False);
end;

procedure TConverter.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  Data.Close;
  ADOConnection.Close;
  Ini.Free;
  Codes.Free;
  gThr.FreeOnTerminate := True;
  gThr.Terminate;
end;

procedure TConverter.Timer1Timer(Sender: TObject);
begin
Run;
end;

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

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

end.
По ракетам и хоккею - Россияне всех сильней!

Последний раз редактировалось Ky3Heu,; 22.11.2011 в 14:27.
Ky3Heu, вне форума Ответить с цитированием
Старый 22.11.2011, 14:49   #10
Ky3Heu,
Пользователь
 
Регистрация: 01.04.2009
Сообщений: 94
По умолчанию

Нашел ошибку..Запустилась прога как служба и не останавливается.. Но и не отрабатывает((((
По ракетам и хоккею - Россияне всех сильней!
Ky3Heu, вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
vs 2010 и создание службы windows CodeNOT Visual C++ 2 23.05.2011 21:29
Создание службы Windows GenniY Общие вопросы Delphi 2 14.04.2010 13:51
Службы Bat{CMD}_Men Общие вопросы Delphi 0 04.10.2009 14:50
Создание службы в Windows goblinyara Общие вопросы Delphi 8 03.01.2009 19:57
службы bloood Общие вопросы C/C++ 1 02.04.2007 02:04