[win32] Programma als service uitvoeren *

Pagina: 1
Acties:
  • 441 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
Ik heb een (console) applicatie gemaakt die als een op zich zelf staande Windows service uitgevoerd moet worden.

Via de search kwam ik op Firedeamon maar om dat te kunnen gebruiken moet firedeamon geinstalleerd blijven op de server waar mijn app komt te draaien (win2000) en dat willen we niet... (de executable van de service is firedeamon.exe)

Nu heb ik met behulp van ntreskit mijn applicatie wel als service toegevoegd maar steeds als ik de service opstart krijg ik een foutmelding dat de service niet gestart kon worden met error 1053: The service did not respond to the start or control request in a timely fashion.

Ik zal dus op een of andere manier mijn applicatie moeten ombouwen tot service, iets met onstart, onstop etc erin.

Kan iemand mij een eindje op weg helpen??

Met google kwam ik er ook niet echt uit...

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Dat kan je niet zomaar doen.

Als je een echte Windows Service wilt maken, dan moet die aan een bepaalde interface voldoen zodat de Service Control Manager die service kan beheren.

Je zult een nieuw project moeten starten (welke compiler en IDE gebruik je?), en daar kiezen voor een projecttype 'Windows Service' oid.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
MS Visual Studio.net

Maar bij Visual C++ applications kan ik niet iets kiezen om een service te maken... (bij visual C# apps daarentegen wel)

Acties:
  • 0 Henk 'm!

  • The End
  • Registratie: Maart 2000
  • Laatst online: 11:42

The End

!Beginning

Een service onder Windows is niets meer dan een console application met een aantal control handlers. (Standaard start/stop/shutdown)
Kijk maar een bij de functie 'StartServiceCtrlDispatcher'; daar staat ook een voorbeeld van hoe je een service main functie moet schrijven.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Of je gebruikt gewoon de tool srvany:
http://www.iopus.com/guides/srvany.htm

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Je hoeft alleen maar een DLL of executable te maken die 'ServiceMain' exporteert. En als je op ServiceMain zoekt bij MSDN staat daar een compleet werkend voorbeeld :)

Ik zou niet weten waarom je een tool ervoor zou moeten gebruiken, de C++ code om een service te managen en zichzelf te laten installeren is nog geen 100 regels.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
De enige reden waarom ik die tool (van Microsoft) voorstelde is omdat je je applicatie er niet voor hoeft aan te passen.

Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-09 18:27

pjvandesande

GC.Collect(head);

bigbeng schreef op 18 mei 2004 @ 14:09:
De enige reden waarom ik die tool (van Microsoft) voorstelde is omdat je je applicatie er niet voor hoeft aan te passen.
Je implimenteerd toch gewoon de benodigde interfaces?

Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
questa schreef op 18 mei 2004 @ 14:13:
[...]


Je implimenteerd toch gewoon de benodigde interfaces?
Hmm, gezien de topicstart heb je een punt. De TS is bereid om zn applicatie om te bouwen.

Ervan uitgaande dat Visual C++ de ontwikkeltool is die gebruikt wordt:
http://www.codeguru.com/C...rvices/article.php/c5701/

Maar goed: met de manier die ik eerder noemde kun je op eenvoudige wijze een service maken van een willekeurige executable.

Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
iig bedankt voor alle reacties maar ik kom er niet uit

Ik heb de volgende code gecopy paste:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "stdafx.h"
#include "Windows.h"
#include "Winsvc.h"
#include "time.h"

SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
BOOL InstallService();
BOOL DeleteService();

int main(int argc, char* argv[])
{
    SERVICE_TABLE_ENTRY DispatchTable[]={{"dmsupdater",ServiceMain},{NULL,NULL}};  
    StartServiceCtrlDispatcher(DispatchTable); 
    return 0;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
    DWORD status; 
    DWORD specificError; 

    m_ServiceStatus.dwServiceType        = SERVICE_WIN32; 
    m_ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
    m_ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP; 
    m_ServiceStatus.dwWin32ExitCode      = 0; 
    m_ServiceStatus.dwServiceSpecificExitCode = 0; 
    m_ServiceStatus.dwCheckPoint         = 0; 
    m_ServiceStatus.dwWaitHint           = 0; 
 
    m_ServiceStatusHandle = RegisterServiceCtrlHandler("dmsupdater",ServiceCtrlHandler);  
    if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 
    { 
        return; 
    }     

    m_ServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
    m_ServiceStatus.dwCheckPoint         = 0; 
    m_ServiceStatus.dwWaitHint           = 0;  
    if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus)) 
    { 

    } 
    
    bRunning=true;
    while(bRunning)
    {       
        Sleep(3000);    
        //Place Your Code for processing here....
    }

    return; 
}


void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
    switch(Opcode) 
    { 
        case SERVICE_CONTROL_PAUSE: 
            m_ServiceStatus.dwCurrentState = SERVICE_PAUSED; 
            break; 
 
        case SERVICE_CONTROL_CONTINUE: 
            m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
            break; 
 
        case SERVICE_CONTROL_STOP: 
            m_ServiceStatus.dwWin32ExitCode = 0; 
            m_ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            m_ServiceStatus.dwCheckPoint    = 0; 
            m_ServiceStatus.dwWaitHint      = 0; 
 
            SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);

            bRunning=false;

            break;
 
        case SERVICE_CONTROL_INTERROGATE: 
            break; 
    }      
    return; 
}


Als ik deze app in de lijst met Windows services wil starten krijg ik zon foutmelding dat de service niet reageert (does not rspond in a timeley fashion oid)

Bij het deguggen kwam ik erachter dat het bij regel 35 fout gaat:
code:
1
m_ServiceStatusHandle = RegisterServiceCtrlHandler("dmsupdater",ServiceCtrlHandler);


Het resultaat van RegisterServiceCtrlHandler is namelijk een null-pointer. Ik heb dus geen geldige Service Control Handler

Wat doe ik daar dan fout?
dmsupdater is de naam van de service...

Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Nu online

Reptile209

- gers -

Heb je dit al gelezen? (zoeken op MSDN naar RegisterServiceCtrlHandler)
Return Values
If the function succeeds, the return value is a service status handle.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
ja dat had ik er idd bij moeten zetten. De last error is 3221225477. Een waarde die me niets zegt

Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Nu online

Reptile209

- gers -

Dat zou niet mogen kunnen: 3221225477 is 11000000000000000000000000000101 binair. Volgens de beschrijving van GetLastError is een foutcode met bit 29 (tweede van links) op 1 een applicatiecode (en dus niet van het OS). Dat betekent dat je of zelf (misschien via een andere service die niet van jou is) een error zet, of dat je niet meteen GetLastError pakt. Post de relevante code anders eens?

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
De GetLastError staat op de volgende regel van RegisterServiceCtrlHandler

De waarde van GetLastError is ook elke keer hetzelfde

Edit:
Als ik het op de pc van mn collega draai krijg ik precies hetzelfde

[ Voor 24% gewijzigd door Riesjard op 18-05-2004 15:11 ]


Acties:
  • 0 Henk 'm!

  • The End
  • Registratie: Maart 2000
  • Laatst online: 11:42

The End

!Beginning

Je kan een service niet starten zoals je een console application start... Je moet eerst 'CreateService' aanroepen. (vanuit een ander programma)
Dan pas staat je service geregistreerd bij de service manager en kan je hem via de services snapin starten. (Tijdens het debuggen moet je dit hele mechanisme omzeilen.)

Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
Hoe kom ik er dan achter wat ik verkeerd doe???

Deze regels kloppen toch??
In de main functie:
code:
1
SERVICE_TABLE_ENTRY DispatchTable[]={{"<naam_service>",ServiceMain},{NULL,NULL}};

In de ServiceMain:
code:
1
m_ServiceStatusHandle = RegisterServiceCtrlHandler("<naam_service>",",ServiceCtrlHandler);


Als ik dit compileer en <naam_service> wil starten in de lijst met services krijg ik de foutmelding: Error 1054: The service did not repsond to the start or control request in a timely fashion

Acties:
  • 0 Henk 'm!

  • The End
  • Registratie: Maart 2000
  • Laatst online: 11:42

The End

!Beginning

Riesjard schreef op 18 mei 2004 @ 15:55:
Hoe kom ik er dan achter wat ik verkeerd doe???

Deze regels kloppen toch??
In de main functie:
code:
1
SERVICE_TABLE_ENTRY DispatchTable[]={{"<naam_service>",ServiceMain},{NULL,NULL}};

In de ServiceMain:
code:
1
m_ServiceStatusHandle = RegisterServiceCtrlHandler("<naam_service>",",ServiceCtrlHandler);


Als ik dit compileer en <naam_service> wil starten in de lijst met services krijg ik de foutmelding: Error 1054: The service did not repsond to the start or control request in a timely fashion
Je moet ervoor zorgen dat je nadat je de service control handler hebt geregistreerd (RegisterServiceCtrlHandler), dat je dan meteen 'setservicestatus' aanroept, met of 'dwCurrentState' op 'SERVICE_RUNNING' of 'SERVICE_START_PENDING'.
Hoe heb je trouwens 'createservice' aangeroepen?

Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
The End schreef op 18 mei 2004 @ 16:07:
[...]
Je moet ervoor zorgen dat je nadat je de service control handler hebt geregistreerd (RegisterServiceCtrlHandler) ...
Dat registreren gaat dus niet goed --> resultaat van RegisterServiceCtrlHandler is een lege pointer
The End schreef op 18 mei 2004 @ 16:07:
Hoe heb je trouwens 'createservice' aangeroepen?
Niet.... Dit is toch het toevoegen van je applicatie aan de lijst van services???
Uit MSDN:
A service configuration program uses the CreateService function to install a service in a SCM database.
Dat gebeurt in mijn geval niet in de applicatie zelf maar met sc.exe van Windows

Acties:
  • 0 Henk 'm!

  • Riesjard
  • Registratie: April 2003
  • Niet online
Ik heb het eindelijk opgelost

Dat de RegisterServiceCtrlHandler een null-pointer opleverde was te verklaren door deze post van The End (thnx)

Toen ben ik dus weer gaan klooien om de service op te starten vanuit het services scherm maar ik kreeg meteen na het opstarten die 1053 error (not respond in timely fashion)

Echter.
Op de plaats vanwaar de service opgestart wordt miste ik een bestand die ik nodig heb voor mn applicatie |:(

Iedereen bedankt voor de hulp
Pagina: 1