StartServiceCtrlDispatcher

Dear fellow programmers,

Congratulations for your extremely useful and nice Web and C++ tutorial (which I read eagerly)! I have invested a couple of days digressing about a problem, and I cannot find out the solution.

I am "migrating" a piece of software from UNIX to Windows environment, and I would like it to behave as a Windows Service. Actually, Microsoft Support Web provides a clear example (http://msdn.microsoft.com/en-us/library/bb540476%28v=VS.85%29.aspx) which I have compiled it, and it works fine. No problem at all, yet. The example provided by Microsoft in such Web is written in raw C and I would like to re-write it in a C++ style, following Object Orient paradigm (no reason why, it is just because I am very bored ;) ).

I thought it should be pretty easy and quick (variable ->variable data member, function -> member function). The part that is causing the problems is the following: (Firstly I will show you a fragment of the working example provided by Microsoft (the cornerstone for the issue), then a scribble of what I am trying, and finally how to reproduce the erroneous behavior with original Microsoft's example):


/* Original code from Microsoft example */
/* Only installation fragment is shown (because i guess the problem is around here ...) */
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
void __cdecl _tmain(int argc, TCHAR *argv[]) 
{ 

    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if( lstrcmpi( argv[1], TEXT("install")) == 0 )
    {
        SvcInstall();
        return;
    }

    // TO_DO: Add any additional services for the process to this table.
    SERVICE_TABLE_ENTRY DispatchTable[] = 
    { 
        { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, 
        { NULL, NULL } 
    }; 
 
    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.


    if (!StartServiceCtrlDispatcher( DispatchTable )) 
    { 
        SvcReportEvent(TEXT("XXX_StartServiceCtrlDispatcher")); 
    } 
} 


#####################################################################

/* My code would look like this after ruining the previous example up */
// Installation and start-up fragment
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
void __cdecl _tmain(int argc, TCHAR *argv[]) 
{

	HANDLE wThread[numThreads];

	wThread[0]= CreateThread(NULL, 0, InstallMain, NULL, 0, NULL);
	WaitForSingleObject( wThread[0], INFINITE );
	
	wThread[1]= CreateThread(NULL, 0, StartMain, NULL, 0, NULL);
	WaitForSingleObject( wThread[1], INFINITE );

} 

DWORD WINAPI InstallMain ( LPVOID arg )
{
	Svc::fileLog << "$$$ : Entering InstallMain " << endl;
	Svc::SvcInstall();
	return 0;

        /* ?????? This is the mother of the lamb ... StartServiceCtrlDispatcher */
	SERVICE_TABLE_ENTRY DispatchTable[] = 
	{
		{ SVCNAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, 
		{ NULL, NULL } 
	};

	Svc::fileLog << "$$$ : Before StartServiceCtrlDispatcher " << endl;
	if (!StartServiceCtrlDispatcher( DispatchTable )) 
	{ 
		Svc::fileLog << "$$$ : WTF ???" << endl;
	}

}

DWORD WINAPI StartMain ( LPVOID arg )
{
	Svc::fileLog << "$$$ : Entering StartMain " << endl;
	Svc::DoStartSvc();
	return 0;
}


VOID WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
	Svc::fileLog << "$$$ : Entering ServiceMain " << endl;
	Svc::SvcMain( dwArgc, lpszArgv );

}



The result that I ALWAYS get (I have done several trials using differnt approachs) is always the same: the service is installed but it is not able to start-up. I get exactly the same result as if, in the original Microsoft's code, I would remove the StartServiceCtrlDispatcher part, as follow:


// Installation fragment
1
2
3
4
5
6
7
8
9
10
11
void __cdecl _tmain(int argc, TCHAR *argv[]) 
{ 
    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if( lstrcmpi( argv[1], TEXT("install")) == 0 )
    {
        SvcInstall();
        return;
    }
} 


Sorry for the mesh... For sure, I am doing something wrong, but I don't know what. Please, could you give any suggestion/hint or help?

Thanks in advance and kind regards!!!
S2
Last edited on
The StartServiceCtrlDispatcher function connects the main thread of a service process to the service control manager, which causes the thread to be the service control dispatcher thread for the calling process.
Thanks kbw, for you thorough support! Now it works fine.

Cheers
Topic archived. No new replies allowed.