Usługa systemowa nie odpowiada na sygnał uruchomienia

0

Witam,
Przeszperałem i wypróbowałem w necie wszystko co się dało żeby znaleźć rozwiązanie ale bez skutecznie. Piszę usługę mam ją zainstalowaną w systemie widoczna jest w services.msc, w kodzie w OnExecute mam:

 while not Terminated do
    ServiceThread.ProcessRequests(True);

i pomimo uruchomienia z services.msc lub z CMD za pomocą net start zawsze dostaje usługa nie odpowiada na sygnał uruchomienia. Dodałem w OnCreate kod zapisujący jakieś info do pliku to to się wykonuje, ale jak dodam w OnExecute lub w OnStart żeby coś zapisała do pliku to tego nie widać czyli w ogóle się to nie wykonuje tylko dlaczego i czy system potrzebuje dostać od mojej usługi jakiś sygnał że się uruchomiła czy co? Dodam że mam Win8 Pro pod Win7 Pro sytuacja wygląda tak samo

0

z tego linka już ćwiczyłem wszystko ale jakoś chyba pominąłem sposób instalacji usługi

sc create myservice1 binpath= "c:\MyService\ServiceApp.exe myservice1"

bo myśłałem że to bez znaczenia a jednak pomogło więc temat do zamknięcia.

A działa tylko z tym kodem:

procedure TMyService.ServiceCreate(Sender: TObject);
begin
  if (System.ParamCount >= 1) and not CharInSet(ParamStr(1)[1], SwitchChars) then
    Name := ParamStr(1);
end; 
0

A musi to być koniecznie w VCL? Może moja prosta przykładowa usługa pisana w WinAPI się na coś nada? Docelowo sprawdzała się. Ale mam tak wkurzający dysk na kablu USB i to jest Western Digital 320 GB model już obecnie nieco leciwy i podłączany nie jak teraz kablem USB z wtyczką dwustronną, tylko taki model z kablem jak do aparatów OLYMPUS.

Takowa usługa sprawdzała się mi wcześniej, żeby nie czekać aż dysk się wzbudzi po dłuższym nie odowływaniu się do niego. Gdyż nic co kombinowałem w sysyemie żeby ten cały czas podłączony dysk "nie spał" nie działalo. Niestety dyskowi zdarza się rozłączyć i tak przy tym wzbudzaniu, także póki co zarzuciłem tę uslugę i jej nie odpalam. Może jednak Tobie się ten kod do czegoś przyda jako material poglądowy. Albo komuś innemu. Kompilowane pod Delphi 7. Bazowy kod wzięty chyba z tłumaczenia czegoś z C++.

0

Dzięki olesio przeanalizuje sobie to bo szczerze to pierwszy raz piszę usługę. A tak przy okazji wszystko mi działa tak jak chciałem, tylko mam jeszcze problem przy zatrzymywaniu usługi. Po uruchomieniu usługi startuje sobie wątek z pętlą:

while Zakoncz <> True do
begin
...
end;

i kończę usługę za pomocą:

var 
  GlownyWatek: TNasluchujPolaczenia;
..

procedure TNasluchujPolaczenia.ZatrzymajSerwer;
begin
    Self.Zakoncz := True;
end;

procedure TNasluchujPolaczenia.Execute;
begin
  while Zakoncz <> True do
  begin
  ..
  end;
  // po zatrzymaniu uslugi czyli po ServiceStop wszystko co jest za pętlą while się nie wykonuje a usługa się zatrzymuje poprawie z poziomu windowsa
  Terminate;
end;

constructor TNasluchujPolaczenia.Create;
begin
  inherited Create(False);
  FreeOnTerminate := True;
end;

destructor TNasluchujPolaczenia.Destroy;
begin
  //tu mam polecenie wpisujące coś do loga i się nie wykonuje
  inherited;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  if GlownyWatek <> nil then
  begin
    GlownyWatek.ZatrzymajSerwer;
    GlownyWatek := nil;
  end;
//w tym miejscu mam wpis do loga i on się pojawia chociaż nie wszystko się wykonało w wątku
end;

A jak wszystko wkleję do zwykłej aplikacji to wszystko działa tak jak trzeba. W usłudze nawet dodałem dodatkową zmienną boolean i pętle while czekająca na wykonanie się Destroy to wtedy zatrzymywanie usługi trwa w nieskończoność i się nie zatrzymuje a w zwykłej aplikacji wszystko jest ok, zatrzymuje się od razu wątek i Destroy też się wykonuje.

0

Dobra znalazłem, problemem było to że w Execute jedna funkcja się blokuje a dokładnie accept() od socketów tylko nie wiem dlaczego bo to samo w wersji aplikacji się nie blokuje bo mam dodane:

WSAAsyncSelect(Gniazdo, Handle, WM_USER, FD_READ or FD_ACCEPT); 

a przy usłudze to nie działa tylko dlaczego? Domyślam się że uchwyt jest problemem tylko co zamiast tego podać żeby w usłudze accept() nie blokował działania pętli.

0

Jeśli zależy Tobie na obsłudze poprzez usługę serwera czy bycia klientem TCP, to posiłkuj się Simple TCP. Jest idealne do projektów WinAPI. Z pisaniem tego po swojemu nie umiem nic doradzić, bo nie mam doświadczenia.

0

Nie chciałbym nic zmieniać bo tak naprawdę mam wszystko gotowe na socketach i przetestowane tylko chciałem to przerzucić z aplikacji na usługę. Siedzę nad tym kilkanaście godzin i cały czas to WSAASyncSelect() nie działa, w sensie nie sprawia że accept() się nie blokuje. Sprawdziłem uchwyt na kilka sposobów wydaje mi się że to jest ok, próbowałem zmieniać parametr z WM_USER na WM_APP ale to też nic nie dało ogólnie wywołanie funkcji WSAAsyncSelect zwraca wartość błedu -1 a jak jest wszystko ok to powinno być 0 a u mnie w usłudze jest -1 a w aplikacji 0.

0

Jaka wersja Delphi ?
Dodaj taką linię Application.DelayInitialize := True; przed Application.Initialize;

0

Używam XE4, Application.DelayInitialize to raczej pomocne jest do startowania usługi, ale teraz problem jest z WSAAsyncSelect()

1

Rozwiązane. Problem był uchwyt, rozwiązaniem okazało się użycie AllocateHWnd(MyMessageProc). Na rozwiązanie nakierowano manie na StackOverflow, link do mojego wątku http://stackoverflow.com/questions/30153201/delphi-wsaasyncselecy-not-working-in-windows-services-apliaction

1 użytkowników online, w tym zalogowanych: 0, gości: 1