Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.09;
Скачать: CL | DM;

Вниз

Проблема с написанием Service а   Найти похожие ветки 

 
patrick1968 ©   (2008-02-11 17:24) [0]

Появилась такая задача, решить которую надумал при помощи сервиса (до этого с этим не сталкивался), тема простая в случае появления определенного файла в определенном месте его необходимо перекинуть в др. место (наверное всё просто да только не работает) вот код:

unit Unload1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ActiveX, IniFiles,
 DB, ADODB;

type
 TUnload = class(TService)
   OraConnection: TADOConnection;
   procedure ServiceExecute(Sender: TService);
   procedure ServiceStart(Sender: TService; var Started: Boolean);
 private
   { Private declarations }
 public
   QDesk : integer;
   TempPath, arrPath, ConnectStringIn, ConnectStringOut : string;
   arrDesk : array of string;
   function GetServiceController: TServiceController; override;
   { Public declarations }
 end;

var
 Unload: TUnload;

implementation

{$R *.DFM}

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

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

procedure TUnload.ServiceExecute(Sender: TService);
begin
 CoInitialize(nil);
 while not terminated do begin
              FileCreate(arrDesk[0] + "cash001s.db");
    if FileExists(arrDesk[0] + "cash001.db")
       then begin
              FileCreate(arrDesk[0] + "cash001s.db");
              MoveFile(PChar(arrDesk[0] + "cash001.db"),PChar(TempPath + "cash001.db"));
       end;
    serviceThread.ProcessRequests(false);
    CoUnInitialize;
 end;
end;

procedure TUnload.ServiceStart(Sender: TService; var Started: Boolean);
var UnloadIni : TIniFile;
    ind, idx : integer;
begin
 CoInitialize(nil);

 UnloadIni := TIniFile.Create("prUnload.ini");
 if not FileExists("prUnload.ini")
    then begin
          UnloadIni.WriteInteger( "MAIN", "QDESK", 1);
          UnloadIni.WriteString( "MAIN", "TEMPPATH", "C:\");
          UnloadIni.WriteString( "MAIN", "ARRPATH", "");
          UnloadIni.WriteString( "MAIN", "CONNECTSTRING_IN", "");
          UnloadIni.WriteString( "MAIN", "CONNECTSTRING_OUT", "");
          QDesk := UnloadIni.ReadInteger( "MAIN", "QDESK", 1);
          TempPath := UnloadIni.ReadString( "MAIN", "TEMPPATH", "");
          ArrPath := UnloadIni.ReadString( "MAIN", "ARRPATH", "");
          ConnectStringIn := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_IN", "");
          ConnectStringOut := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_OUT", "");
         end
       else begin
             QDesk := UnloadIni.ReadInteger( "MAIN", "QDESK", 1);
             TempPath := UnloadIni.ReadString( "MAIN", "TEMPPATH", "");
             ArrPath := UnloadIni.ReadString( "MAIN", "ARRPATH", "");
             ConnectStringIn := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_IN", "");
             ConnectStringOut := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_OUT", "");
            end;
 UnloadIni.Free;

 try
  OraConnection.ConnectionString := ConnectStringIn;
  OraConnection.Connected := true;
 except
 end;

 SetLength( arrDesk, QDesk);
 ind := 0;
 idx := 1;
 arrDesk[ind] := "";
 while (idx <= Length(arrPath)) do begin
    if arrPath[idx] <> ","
      then arrDesk[ind] := arrDesk[ind] + arrPath[idx]
      else begin
            inc(ind);
            arrDesk[ind] := "";
           end;
    inc(idx);
 end;

 CoUnInitialize;

end;


в стартовой процедуре определил переменные, которые нужны при Execute"е, только там она их не видит почему-то, помогите разобраться, заранее благодарен.


 
Сергей М. ©   (2008-02-11 17:31) [1]


> в стартовой процедуре определил переменные, которые нужны
> при Execute"е


Это какие же ?

И зачем в обработчике OnExecute вызовы CoInitialize/CoUnInitialize ?


 
Palladin ©   (2008-02-11 17:45) [2]


> patrick1968 ©   (11.02.08 17:24)

ну как бы задача понятна... проблема только непонятна... кто на ком стоял...


 
patrick1968 ©   (2008-02-11 17:47) [3]

массив arrDesk, который определяется в старте и объявлен в разделе public, а CoInitialize/CoUnInitialize на будущее т.к. далее буду использовать ADO вычитал на каком-то форуме об этой необходимости.(вообще написание сервисов для меня - новинка, поэтому может есть ссылка на толковую статью, чтобы не задавать слишком простых вопросов)


 
Palladin ©   (2008-02-11 17:49) [4]


> массив arrDesk, который определяется в старте и объявлен
> в разделе public

ну и чего с того то? проблемма где? я вот в упор понять не могу


> в стартовой процедуре определил переменные, которые нужны
> при Execute"е, только там она их не видит


что это вообще значит...


>  CoInitialize/CoUnInitialize на будущее т.к. далее буду
> использовать ADO вычитал на каком-то форуме об этой необходимости

их необходимость более чем под вопросом


 
patrick1968 ©   (2008-02-11 17:57) [5]

проблема в том, что прога не работает (MoveFile) не перетаскивается файл


 
Palladin ©   (2008-02-11 18:00) [6]


> проблема в том, что прога не работает

замечательная проблема


>  (MoveFile) не перетаскивается файл

ты это визуально определил, аль GetLastError поймал?


 
patrick1968 ©   (2008-02-11 18:03) [7]

ВИзуально, а что разве так не должно быть?


 
Palladin ©   (2008-02-11 18:03) [8]

мда... ознакомился подробней с твоим кодом...
бред...


 
Palladin ©   (2008-02-11 18:06) [9]

идем читаем
http://www.delphimaster.ru/articles/panov/index.html

потом долго думаем...
кстати пока думаем, форматируем исходный код и пытаемся объяснить мне почему CoInitialize вызвано перед циклом While, а CoUninitialize вызывается на каждой итерации... честно честно, мне очень интересно...


 
ketmar ©   (2008-02-11 19:16) [10]

что это ([0]) было? %-)

---
Understanding is not required. Only obedience.


 
Slym ©   (2008-02-12 04:41) [11]

в ServiceStart запускай дополнительный поток, в котором делай все что угодно: CoInitialize, создавай конекшены, мувь файло... ServiceExecute не для этого


 
Slym ©   (2008-02-12 04:42) [12]

в ServiceStart запускай дополнительный поток, в котором делай все что угодно: CoInitialize, создавай конекшены, мувь файло... ServiceExecute не для этого


 
Сергей М. ©   (2008-02-12 08:27) [13]


> patrick1968 ©   (11.02.08 17:47) [3]
>
> массив arrDesk, который определяется в старте


При старте он не определяется.

Определяется он как раз в public, создается (с нулевой длиной) при создании объекта UnLoad, а при старте просто изменяется его длина.


> прога не работает (MoveFile) не перетаскивается файл
>


А причем здесь тогда

> она их не видит


?

Видимость переменной - понятие, относящееся ко времени компиляции, а не ко времени выполнения.


 
ANB   (2008-02-12 09:46) [14]


> FileCreate(arrDesk[0] + "cash001s.db");

Скажи, пожалуйста, что делает у тебя этот оператор ?

На будующее :
1) Выкини сервис и напиши сначала обычное приложение, в котором нужные тебе действия выполняй под кнопкой.
2) Учти граблю : файл может быть обнаружен экзистом, но при этом еще писаться, посему ты должен убедится, что файл уже весь записали, и только потом его перемещать.


 
patrick1968 ©   (2008-02-12 11:22) [15]

Сервис выкидывал, делал всё под кнопкой - работает как надо, а все эти операторы вставлял для проверки, оригинальный код Execute следующий

procedure TUnload.ServiceExecute(Sender: TService);
begin
CoInitialize(nil);
while not terminated do begin
   if FileExists(arrDesk[0] + "cash001.db")
      then begin
             MoveFile(PChar(arrDesk[0] + "cash001.db"),PChar(TempPath + "cash001.db"));
      end;
   serviceThread.ProcessRequests(false);
end;
   CoUnInitialize;
end;

причем если удаляю экзист, и просто на том месте создаю файл с путем arrDesk[0], только создает она его не там где надо а в system32, получается так что в данной ситуации можно использовать только потоки?


 
Dennis I. Komarov ©   (2008-02-12 11:45) [16]

> [15] patrick1968 ©   (12.02.08 11:22)

Остовной поток сервиса - для его управления. Все действия в дополнительные нити.

> причем если удаляю экзист, и просто на том месте создаю
> файл с путем arrDesk[0], только создает она его не там где
> надо а в system32, получается так что в данной ситуации
> можно использовать только потоки?


ЗЫ У тебя проблемы с CurrentDir


 
ANB   (2008-02-12 12:21) [17]


> работает как надо

Начни писать длинннный файл. А пока он пишется - нажми кнопку. Удивись.


 
patrick1968 ©   (2008-02-12 13:04) [18]

Попытался через дополнительный поток

вот код

unit Unload1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ActiveX, IniFiles,
 DB, ADODB;

type

 TMainThread = class(TThread)
 private
 public
   QDesk : integer;
   TempPath, arrPath, ConnectStringIn, ConnectStringOut : string;
   arrDesk : array of string;
   OraConnection: TADOConnection;
   constructor Create;
 protected
    procedure DoWork;
    procedure Execute; override;
 end;

 TUnload = class(TService)
   OraConnection: TADOConnection;
   procedure ServiceExecute(Sender: TService);
 private
   { Private declarations }
 public
   function GetServiceController: TServiceController; override;
   { Public declarations }
 end;

var
 MainThread : TMainThread;
 Unload: TUnload;

implementation

{$R *.DFM}

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

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

constructor TMainThread.Create;
var UnloadIni : TIniFile;
    ind, idx : integer;
begin
 inherited Create(True);    

 UnloadIni := TIniFile.Create("prUnload.ini");
 if not FileExists("prUnload.ini")
    then begin
          UnloadIni.WriteInteger( "MAIN", "QDESK", 1);
          UnloadIni.WriteString( "MAIN", "TEMPPATH", "C:\");
          UnloadIni.WriteString( "MAIN", "ARRPATH", "");
          UnloadIni.WriteString( "MAIN", "CONNECTSTRING_IN", "");
          UnloadIni.WriteString( "MAIN", "CONNECTSTRING_OUT", "");
          QDesk := UnloadIni.ReadInteger( "MAIN", "QDESK", 1);
          TempPath := UnloadIni.ReadString( "MAIN", "TEMPPATH", "");
          ArrPath := UnloadIni.ReadString( "MAIN", "ARRPATH", "");
          ConnectStringIn := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_IN", "");
          ConnectStringOut := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_OUT", "");
         end
       else begin
             QDesk := UnloadIni.ReadInteger( "MAIN", "QDESK", 1);
             TempPath := UnloadIni.ReadString( "MAIN", "TEMPPATH", "");
             ArrPath := UnloadIni.ReadString( "MAIN", "ARRPATH", "");
             ConnectStringIn := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_IN", "");
             ConnectStringOut := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_OUT", "");
            end;
 UnloadIni.Free;

 try
  OraConnection.ConnectionString := ConnectStringIn;
  OraConnection.Connected := true;
 except
 end;

 SetLength( arrDesk, QDesk);
 ind := 0;
 idx := 1;
 arrDesk[ind] := "";
 while (idx <= Length(arrPath)) do begin
    if arrPath[idx] <> ","
      then arrDesk[ind] := arrDesk[ind] + arrPath[idx]
      else begin
            inc(ind);
            arrDesk[ind] := "";
           end;
    inc(idx);
 end;

 Self.Priority := tpHighest;
 Resume;                      
end;

procedure TMainThread.DoWork;
begin
  if FileExists(arrDesk[0] + "cash001.db")
     then begin
           FileCreate(arrDesk[0] + "cash001s.db");
          end;
end;

procedure TMainThread.Execute;
begin
    while not Terminated do
    begin
        Synchronize(DoWork);
        Sleep(1000);
    end;
end;

procedure TUnload.ServiceExecute(Sender: TService);
begin
MainThread := TMainThread.Create;
end;

end.

в итоге при старте службы пишет что служба была запущена а затем остановлена т.к. нечего делать. Может есть какой пример по написанию службы при помощи создания доп потоков?


 
Palladin ©   (2008-02-12 13:06) [19]

да забудь ты про SeviceExucte!
поток стартуй на ServiceStart
поток останавливай на ServiceStop


 
Dennis I. Komarov ©   (2008-02-12 13:20) [20]

> procedure TUnload.ServiceExecute(Sender: TService);
> begin
> MainThread := TMainThread.Create;
> end;
>
> end.
>
> в итоге при старте службы пишет что служба была запущена
> а затем остановлена т.к. нечего делать. Может есть какой
> пример по написанию службы при помощи создания доп потоков?

После того, как служба создала поток, ее действие закончилось - она и остановилася

написать службу при помощи создания доп. потоков - низя :)

Сперва разберись с ними по отдельности, а потом склеишь.


 
patrick1968 ©   (2008-02-12 13:28) [21]

Так сделал, служба стартует нормально только переменные которые фигурируют в конструкторе (например arrDesk[0] которая на том этапе равна "D:\CASSA\") в процедуре DoWork равна "" наверное есть какая-то хитрость?


 
Сергей М. ©   (2008-02-12 13:31) [22]


> переменные которые фигурируют в конструкторе


> в процедуре DoWork


Какой такой "конструктор" ? Какая DoWork ?!
Ни того ни другого в приведенном коде и в помине нет


 
Palladin ©   (2008-02-12 13:31) [23]


> procedure TMainThread.Execute;
> begin
>     while not Terminated do
>     begin
>         Synchronize(DoWork);
>         Sleep(1000);
>     end;
> end;

ты опять бредишь?
и по ссылке мы не ходили по моей
и гдето про synchronize узнали
и решили что это круто
и заюзали


 
Palladin ©   (2008-02-12 13:33) [24]


> Self.Priority := tpHighest;

а за это вообще пожизненный эцих с гвоздями


 
Slym ©   (2008-02-12 13:35) [25]

   while not Terminated do
   begin
       Synchronize(DoWork);
       Sleep(1000);
   end;

Откуда эти мертвяки лезут? А выкрутасы с ini на елку вместо гирлянд весить...
сделай модуть (unit) со своим потоком... отладь его в обычном приложении... а уж потом его к сервису приленкуешь


 
Slym ©   (2008-02-12 13:37) [26]

и OraConnection у тебя для понта или реально гдето используется?


 
patrick1968 ©   (2008-02-12 13:47) [27]

Да все эти выкрутасы с этих ссылок и взял, из примеров


 
Slym ©   (2008-02-12 13:56) [28]

var
 UnloadIni : TIniFile;
begin
 UnloadIni := TIniFile.Create("prUnload.ini");
 try
   if not FileExists(UnloadIni.FileName) then
   begin
     UnloadIni.WriteInteger( "MAIN", "QDESK", 1);
     UnloadIni.WriteString( "MAIN", "TEMPPATH", "C:\");
     UnloadIni.WriteString( "MAIN", "ARRPATH", "");
     UnloadIni.WriteString( "MAIN", "CONNECTSTRING_IN", "");
     UnloadIni.WriteString( "MAIN", "CONNECTSTRING_OUT", "");
   end;
   QDesk := UnloadIni.ReadInteger( "MAIN", "QDESK", 1);
   TempPath := UnloadIni.ReadString( "MAIN", "TEMPPATH", "");
   ArrPath := UnloadIni.ReadString( "MAIN", "ARRPATH", "");
   ConnectStringIn := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_IN", "");
   ConnectStringOut := UnloadIni.ReadString( "MAIN", "CONNECTSTRING_OUT", "");
 finally
   UnloadIni.Free;
 end;


 
ketmar ©   (2008-02-12 14:02) [29]

>[23] Palladin © (2008-02-12 13:31:00)
как это «где-то»? очен даже известно, где. некий неприкасаемый это популяризировал, чтоб ему ни дна, ни покрышки.

---
Understanding is not required. Only obedience.


 
Palladin ©   (2008-02-12 14:10) [30]


> [27] patrick1968 ©   (12.02.08 13:47)

та все эти выкрутасы ты тупо скопировал и необоснованно использовал, непонимая чего к чему, а по ссылкам они очень даже обосновано использованы...


 
Dennis I. Komarov ©   (2008-02-12 15:09) [31]

> [29] ketmar ©   (12.02.08 14:02)

Злой ты какой-то сегодня :)


> [27] patrick1968 ©   (12.02.08 13:47)

Переходим к убитым енотам: 50


 
ketmar ©   (2008-02-12 15:11) [32]

>[31] Dennis I. Komarov © (2008-02-12 15:09:00)
>Злой ты какой-то сегодня :)

не спал ещё. %-)

---
Understanding is not required. Only obedience.


 
Palladin ©   (2008-02-12 15:27) [33]


> [32] ketmar ©   (12.02.08 15:11)

w3k ждал? :)


 
Leonid Troyanovsky ©   (2008-02-12 15:28) [34]


> Slym ©   (12.02.08 13:35) [25]

> Откуда эти мертвяки лезут?

Из вредных советов.
http://podgoretsky.com/DM/BadTips.html#bt-04

--
Regards, LVT.


 
ketmar ©   (2008-02-12 15:33) [35]

>[33] Palladin © (2008-02-12 15:27:00)
вообще-то жрачки. %-)

---
Understanding is not required. Only obedience.


 
Сергей М. ©   (2008-02-12 15:35) [36]


> в случае появления определенного файла в определенном месте
> его необходимо перекинуть в др. место


Логика, ведущая в тупик.



Страницы: 1 вся ветка

Текущий архив: 2008.03.09;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.024 c
4-1184658001
Artog
2007-07-17 11:40
2008.03.09
SetupDiGetDeviceInterfaceDetail - ошибка 1784


2-1202894259
Washington
2008-02-13 12:17
2008.03.09
Двойной щелчок по "чексу" в CheckListBox e


2-1202711082
Dib@zol
2008-02-11 09:24
2008.03.09
Win98 + AlphaBlend = ?


2-1202756973
Jimmy
2008-02-11 22:09
2008.03.09
Событие при перемещении формы


15-1202094345
Slider007
2008-02-04 06:05
2008.03.09
С днем рождения ! 4 февраля 2008 понедельник