Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с сервисами 
:(
    Опции темы
Гость_Felt
Дата 4.7.2005, 04:21 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Написал сервис. Отдельно написал программу установки сервиса. Но похоже в сервисе был глюк и его запуск так и не состоялся. В результате теперь он сидит в "Службах" при этом недоступны все задачи в контекстном меню. Мало того, я не могу его еще и удалить. Использую функцию DeleteService. Менеджер открываю с правами SERVICE_ACCESS_ALL. Как удалить сервис? Как правильно его тестировать?
Все целиком писал на API.
  Вверх
SoWa
Дата 4.7.2005, 05:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 2
Всего: 74



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


--------------------
Всем добра smile
PM MAIL ICQ   Вверх
Guest
Дата 4.7.2005, 09:43 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











теперь я не могу его ни запустить, ни удалить. когда изменяю тип запуска (авто или еще какой) и жму применить вылетает сообщение типа сервис отмечен к удалению. Перезагружаюсь, он все равно сидит в службах. Задачи недоступны: я не могу ни запустить, ни остановить.
  Вверх
Guest
Дата 4.7.2005, 11:20 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Нет. Все ввроде удалился сервис. Только я теперь даже не знаю, а как тестировать сервис? Пока я пишу программу мне приходится несколько раз компилировать приложение и запускать его. С сервисами это как то проблематично. И еще, а IRC канала своего у вас нету?
  Вверх
Guest
Дата 4.7.2005, 22:53 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Мне просто нужно как то быстро тестировать код без регистрации сервиса, без его удаления и т. д. Код вам не поможет, ошибку я найду сам.

Это сообщение отредактировал(а) Girder - 17.7.2005, 17:56
  Вверх
Rennigth
Дата 5.7.2005, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



Цитата

  Мне просто нужно как то быстро тестировать код без регистрации сервиса

ну и сделай его на время разработки простым exe-шником, или запускай свой
Добавлено @ 16:10
сервис в отладке с параметром как-нибудь /start прикотором будет запускаться он, необязательно же запускать его запускать рукими...


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
SoWa
Дата 5.7.2005, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 2
Всего: 74



Ты что, программу-сервис сразу пишешь?
Пиши просто программу, а потом таким кодом запихивай её в сервисы!

Код

function CreateNTService(ExecutablePath, ServiceName: string): boolean;
var
  hNewService, hSCMgr: SC_HANDLE;
  // Rights: DWORD;
  FuncRetVal: Boolean;
begin
  FuncRetVal := False;
  hSCMgr := OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
  if (hSCMgr <> 0) then
  begin


    hNewService := CreateService(hSCMgr, PChar(ServiceName), PChar(ServiceName),
      STANDARD_RIGHTS_REQUIRED, SERVICE_WIN32_OWN_PROCESS,
      SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
      PChar(ExecutablePath), nil, nil, nil, nil, nil);
    CloseServiceHandle(hSCMgr);
    if (hNewService <> 0) then
      FuncRetVal := true
    else
      FuncRetVal := false;
  end;
  CreateNTService := FuncRetVal;
end;


function DeleteNTService(ServiceName: string): boolean;
var
  hServiceToDelete, hSCMgr: SC_HANDLE;
  RetVal: LongBool;
  FunctRetVal: Boolean;
begin
  FunctRetVal := false;
  hSCMgr := OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
  if (hSCMgr <> 0) then
  begin
    hServiceToDelete := OpenService(hSCMgr, PChar(ServiceName),
      SERVICE_ALL_ACCESS);
    RetVal := DeleteService(hServiceToDelete);
    CloseServiceHandle(hSCMgr);
    FunctRetVal := RetVal;
  end;
  DeleteNTService := FunctRetVal;
end;

function ServiceStart(aMachine, aServiceName: string ): boolean;
// aMachine это UNC путь, либо локальный компьютер если пусто
var
  h_manager,h_svc: SC_Handle;
  svc_status: TServiceStatus;
  Temp: PChar;
  dwCheckPoint: DWord;
begin
  svc_status.dwCurrentState := 1;
  h_manager := OpenSCManager(PChar(aMachine), nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, PChar(aServiceName),
    SERVICE_START or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      temp := nil;
      if (StartService(h_svc,0,temp)) then
        if (QueryServiceStatus(h_svc,svc_status)) then
        begin
          while (SERVICE_RUNNING <> svc_status.dwCurrentState) do
          begin
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);
            if (not QueryServiceStatus(h_svc,svc_status)) then
              break;
            if (svc_status.dwCheckPoint < dwCheckPoint) then
            begin
              // QueryServiceStatus не увеличивает dwCheckPoint
              break;
            end;
          end;
        end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  Result := SERVICE_RUNNING = svc_status.dwCurrentState;
end;


function ServiceStop(aMachine,aServiceName: string ): boolean;
// aMachine это UNC путь, либо локальный компьютер если пусто
var
  h_manager, h_svc: SC_Handle;
  svc_status: TServiceStatus;
  dwCheckPoint: DWord;
begin
  h_manager:=OpenSCManager(PChar(aMachine),nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager,PChar(aServiceName),
    SERVICE_STOP or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      if(ControlService(h_svc,SERVICE_CONTROL_STOP, svc_status))then
      begin
        if(QueryServiceStatus(h_svc,svc_status))then
        begin
          while(SERVICE_STOPPED <> svc_status.dwCurrentState)do
          begin
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);
            if(not QueryServiceStatus(h_svc,svc_status))then
            begin
              // couldn't check status
              break;
            end;
            if(svc_status.dwCheckPoint < dwCheckPoint)then
              break;
          end;
        end;
      end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  Result := SERVICE_STOPPED = svc_status.dwCurrentState;
end;

Это все, что нужно дл яработы с сервисами!

Это сообщение отредактировал(а) Girder - 5.7.2005, 20:31


--------------------
Всем добра smile
PM MAIL ICQ   Вверх
Guest
Дата 7.7.2005, 03:00 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











SoWaЯ об этом уже думал, но мне нужно правильно реагировать на остановку сервиса, запуск, приостановку. Поэтому все так нужно писать сервис.
  Вверх
Elfix
Дата 14.7.2005, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



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

P. S. Моя программа не сервис, но судя по всему любую прогу можно запустить как сервис.
PM MAIL   Вверх
Elfix
Дата 17.7.2005, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Неужели никто никогда не работал с сервисами Windows?
PM MAIL   Вверх
Girder
Дата 17.7.2005, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 25
Всего: 155



Цитата(Elfix @ 17.7.2005, 17:55)
Неужели никто никогда не работал с сервисами Windows?
Работали... работаем... будем работать.

Мы же тут не телепаты... smile Нужен код... или на худой конец тип сервиса... и в чем проблемма.



--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Elfix
Дата 18.7.2005, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Для примера, есть такая программа:
Код
program Project1;

uses
  Windows,
  WinSvc;

var
 hTh, hThread: THandle;

procedure ThreadProc; stdcall;
begin
 while True do
  begin

  end;
end;

procedure CreateService(ServiceName, ExecutablePath: String);
var
 hSCMgr, hService: SC_HANDLE;
begin
 hSCMgr:=OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
 if hSCMgr <> 0 then
  begin
   hService:=WinSvc.CreateService(hSCMgr, PChar(ServiceName), PChar(ServiceName), STANDARD_RIGHTS_REQUIRED, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, PChar(ExecutablePath), nil, nil, nil, nil, nil);
   CloseServiceHandle(hSCMgr);
   if hService <> 0 then
    CloseServiceHandle(hService);
  end;
end;

procedure CheckParams;
var
 i: Byte;
begin
 for i:=1 to ParamCount do
  if ParamStr(i) = '/install' then
   begin
    CreateService('TestService', ParamStr(0));
    ExitProcess(0);
   end;
end;

begin
 CheckParams;
 hThread:=CreateThread(nil, 0, @ThreadProc, 0, 0, hTh);
 WaitForSingleObject(hThread, INFINITE);
 CloseHandle(hThread);
end.
Если программа запущена с параметром /install то происходит автоматическая установка сервиса. После я пытаюсь через панель управления запустить сервис, но ничего не выходит. Менеджер очень долго пытается запустить сервис, но в результате выдает ошибку.
PM MAIL   Вверх
Girder
Дата 18.7.2005, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 25
Всего: 155



Понятно... smile

Для начала сделай вот так:

1. File->New->Other->Service Application

2. http://forum.vingrad.ru/index.php?showtopi...ndpost&p=336679

Как сделаеш... продолжим.


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Elfix
Дата 18.7.2005, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Попробовал сделать так как ты предложил. Сервис установился, потом я его вручную запустил. Все прошло прекрасно. Только мне нужно полностью отказаться от использования встроенных средств Delphi и все сделать только на чистом API. Я не могу понять в чем происходит ошибка, почему сервис не запускается?
Добавлено @ 11:29
Говорят, что любую программу можно запустить как сервис. Мне важно, чтобы прога работала или как обычная прога (в 98x) или как сервис (XP по желанию пользователя, т. е. если он сам запустит с параметром /install).
PM MAIL   Вверх
Girder
Дата 19.7.2005, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 25
Всего: 155



Вот пример накатал... изучай:
Код
program gServ;

uses
  Windows, WinSvc, Messages;

{$R *.res}

type
 TSysCharSet=set of Char;
 TCurrentStatus=(csStopped,csStartPending,csStopPending,csRunning,
                 csContinuePending,csPausePending,csPaused);


var tID,hThread:DWord;
    FStatusHandle:DWord;
    Name:string;
    OldExitProc:Pointer;
    STE:array [0..1] of _Service_Table_Entrya;
    Status:TCurrentStatus;
    AppStart:Boolean;

function AnsiCompareText(const S1, S2: string): Integer;
begin
 Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1), Length(S1), PChar(S2), Length(S2)) - 2;
end;

procedure ReportStatus;
const
 LastStatus:TCurrentStatus = csStartPending;
 NTServiceStatus: array[TCurrentStatus] of Integer =
                  (SERVICE_STOPPED,SERVICE_START_PENDING,
                   SERVICE_STOP_PENDING,SERVICE_RUNNING,
                   SERVICE_CONTINUE_PENDING,SERVICE_PAUSE_PENDING,SERVICE_PAUSED);
 PendingStatus: set of TCurrentStatus = [csStartPending,csStopPending,
                                         csContinuePending,csPausePending];
var
  ServiceStatus: TServiceStatus;
begin
 with ServiceStatus do
  begin
   dwWaitHint:=5000;
   dwServiceType:=SERVICE_WIN32_OWN_PROCESS;
   if Status=csStartPending then dwControlsAccepted:=0 else
    dwControlsAccepted:=SERVICE_ACCEPT_SHUTDOWN or SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE;
   if (Status in PendingStatus)and(Status=LastStatus) then
    Inc(dwCheckPoint) else dwCheckPoint:=0;
   dwCurrentState:=NTServiceStatus[Status];
   dwWin32ExitCode:=0;
   dwServiceSpecificExitCode:=0;
   SetServiceStatus(FStatusHandle, ServiceStatus);
  end;
end;


function ThreadProc(Param:Pointer):DWord; stdcall;
begin
 //главная функции программы - здесь должен быть основной код сервиса.
 //Result:=0;
 while true do
  begin
   Sleep(1000);
   //Какой-то код;
  end;
end;

procedure Handler(CtrlCode: DWord);stdcall;
begin
 case CtrlCode of
  SERVICE_CONTROL_STOP: begin
                          Status:=csStopPending;
                          //Какой-то код;
                          TerminateThread(hThread,0);
                        end;
  SERVICE_CONTROL_SHUTDOWN: begin
                             Status:=csStopPending;
                             //Какой-то код;
                             TerminateThread(hThread,0);
                            end;
  SERVICE_CONTROL_PAUSE: begin
                          Status:=csPausePending;
                          //Какой-то код;
                          Status:=csPaused;
                          SuspendThread(hThread);
                         end;
  SERVICE_CONTROL_CONTINUE: begin
                             ResumeThread(hThread);
                             Status:=csContinuePending;
                             //Какой-то код;
                             Status := csRunning;
                            end;
  SERVICE_CONTROL_INTERROGATE: ReportStatus;
 end; 
 ReportStatus; 
end;

procedure ServiceMain(Argc: DWord; Argv: PLPSTR); stdcall;
begin
 hThread:=CreateThread(nil,0,@ThreadProc,nil,0,tID);
 FStatusHandle:=RegisterServiceCtrlHandler(PChar(Name),@Handler);
 Status:=csStartPending;
 ReportStatus();
 //Какой-то код;
 Status:=csRunning;
 //Какой-то код;
 ReportStatus();
 WaitForSingleObject(hThread,INFINITE);
 CloseHandle(hThread);
 Status:=csStopped;
 //Какой-то код;
 ReportStatus();
end;

procedure DoneServiceApplication(ex:DWord);stdcall;
begin
 ExitProc:=OldExitProc;
end;

function FindCmdLineSwitch(const Switch: string; const Chars: TSysCharSet):Boolean;
var I:Integer;
    S:string;
begin
 for I:=1 to ParamCount do
  begin
   S := ParamStr(I);
   if ((Chars=[])or(S[1] in Chars))and(AnsiCompareText(Copy(S,2,Maxint),Switch)=0) then
    begin
     Result:=True;
     Exit;
    end;
  end;
 Result:=False;
end;

function FindSwitch(const Switch: string): Boolean;
begin
 Result:=FindCmdLineSwitch(Switch,['-', '/']);
end;

function RegisterServices(Install,Start:Boolean):Boolean;
var SvcMgr:DWord;
function InstallService():Boolean;
var Svc:Integer;
    Path:string;
    lpServiceArgVectors:PChar;
begin
 Result:=false;
 Path:=ParamStr(0);
 Svc:=CreateService(SvcMgr,PChar(Name),'Аааа - Сервис',SERVICE_ALL_ACCESS,
                    SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
                    PChar(Path),'',nil,'',nil,'');
 if Svc=0 then exit;
 if Start then
  begin
   lpServiceArgVectors:=nil;
   if StartService(Svc,0,PChar(lpServiceArgVectors)) then Result:=true else DeleteService(Svc);
  end else Result:=true; 
 CloseServiceHandle(Svc);
end;
function UninstallService():Boolean;
var Svc:Integer;
    ServiceStatus:TServiceStatus;
begin
 Result:=false;
 Svc:=OpenService(SvcMgr,PChar(Name),SERVICE_ALL_ACCESS);
 if Svc=0 then exit;
 ControlService(Svc,SERVICE_CONTROL_STOP,ServiceStatus);
 if DeleteService(Svc) then Result:=true;
 CloseServiceHandle(Svc);
end;
begin
 Result:=false;
 SvcMgr:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
 if SvcMgr=0 then exit;
 if Install then Result:=InstallService() else Result:=UninstallService();
 CloseServiceHandle(SvcMgr);
end;

begin
 AppStart:=true;//Запустить(или нет) сервис после инсталяции
 OldExitProc:=ExitProc;
 ExitProc:=@DoneServiceApplication;
 Name:='GirderX';
 if FindSwitch('INSTALL') then  RegisterServices(True,AppStart) else
  if FindSwitch('UNINSTALL') then RegisterServices(False,AppStart) else
   begin
    STE[0].lpServiceName:=PChar(Name);
    STE[0].lpServiceProc:=@ServiceMain;
    STE[1].lpServiceName:=nil;
    STE[1].lpServiceProc:=nil;
    StartServiceCtrlDispatcher(STE[0]);
   end;
end.


PS: Писать все за тебя я не стал - Лень smile

Что бы не ломать дров... почитай: http://www.rsdn.ru/article/baseserv/services_details.xml

Это сообщение отредактировал(а) Girder - 19.7.2005, 11:11


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0588 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.