From: meenu on
Dear all,,,,
I want to run VC program by using service....SO I wrote code for
creating the service.
Code is given below....

void main()
{
SC_HANDLE myService, scm;
printf("Installing RRM Service...\n");
scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);

if (!scm)
{
printf("OpenSCManager fails!", GetLastError());
}

printf("Opened Service Control Manager...\n");

myService = CreateService(
scm, "rrmclient",
"rrmclient",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
"D:\\rrmclient\\Debug\\rrmclient.exe",
0, 0, 0, 0, 0);

if (!myService)
{
printf("CreateService fails!", GetLastError());
}
else
{
printf("Service successfully installed.\n");
}

CloseServiceHandle(myService);
CloseServiceHandle(scm);
}

But when I start this service...

I got error message...
Error 1053: Service could not respond to the start or control request
in a timely fashion.....

Whats the pblem???????
Tanx to all..........

From: Joseph M. Newcomer on
See below...

On 7 Jan 2007 22:12:37 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:

>Dear all,,,,
> I want to run VC program by using service....SO I wrote code for
>creating the service.
>Code is given below....
>
>void main()
>{
>SC_HANDLE myService, scm;
> printf("Installing RRM Service...\n");
> scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
>
> if (!scm)
> {
> printf("OpenSCManager fails!", GetLastError());
> }
>
> printf("Opened Service Control Manager...\n");
>
> myService = CreateService(
> scm, "rrmclient",
> "rrmclient",
> SERVICE_ALL_ACCESS,
> SERVICE_WIN32_OWN_PROCESS,
> SERVICE_DEMAND_START,
> SERVICE_ERROR_NORMAL,
> "D:\\rrmclient\\Debug\\rrmclient.exe",
> 0, 0, 0, 0, 0);
>
> if (!myService)
> {
> printf("CreateService fails!", GetLastError());
> }
> else
> {
> printf("Service successfully installed.\n");
> }
>
> CloseServiceHandle(myService);
> CloseServiceHandle(scm);
>}
>
>But when I start this service...
****
The code above is not a service. The code above is a program that installs a service, and
the service source code is not shown, so there is no way to tell what is going wrong with
the service. The message is certainly correct. Note that hardwiring a path to a program
is almost invariably a Really Really Really Bad Idea; you should put it on the command
line.

Note that you did not have to write any of the above code to isntall a service; you can
use the 'sc' program to do this. So why are you showing us the install code when it is
clear that the error is in the service itself?
****
>
>I got error message...
>Error 1053: Service could not respond to the start or control request
>in a timely fashion.....
>
>Whats the pblem???????
****
The problem almost certainly is that the program you name as the service is not by any
stretch of the imagination a service. If you show the code for the program you think is a
service, we will be able to tell.

Note that a service, in main(), only registers the service with the SCM. And it gives the
address of a ServiceMain. The ServiceMain will then notify the SCM with start-pending
notifications, followed by a run-notification. It will have established the service
control handler, and the service control handler will take care of the SCM requests,
including pause, continue, and shutdown requests. Your service-main function will parse
parameters if relevant and start the threads that are the service, and block until the
service is shut down.

If any of these ideas are unfamiliar, that's why your program isn't working as a service.
A service is *not* just an ordinary C program that is run under the SCM; it is a very
special piece of code specifically constructed to be a service.
joe
****
>Tanx to all..........
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: meenu on

Joseph M. Newcomer wrote:
> See below...
>
> On 7 Jan 2007 22:12:37 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:
>
> >Dear all,,,,
> > I want to run VC program by using service....SO I wrote code for
> >creating the service.
> >Code is given below....
> >
> >void main()
> >{
> >SC_HANDLE myService, scm;
> > printf("Installing RRM Service...\n");
> > scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
> >
> > if (!scm)
> > {
> > printf("OpenSCManager fails!", GetLastError());
> > }
> >
> > printf("Opened Service Control Manager...\n");
> >
> > myService = CreateService(
> > scm, "rrmclient",
> > "rrmclient",
> > SERVICE_ALL_ACCESS,
> > SERVICE_WIN32_OWN_PROCESS,
> > SERVICE_DEMAND_START,
> > SERVICE_ERROR_NORMAL,
> > "D:\\rrmclient\\Debug\\rrmclient.exe",
> > 0, 0, 0, 0, 0);
> >
> > if (!myService)
> > {
> > printf("CreateService fails!", GetLastError());
> > }
> > else
> > {
> > printf("Service successfully installed.\n");
> > }
> >
> > CloseServiceHandle(myService);
> > CloseServiceHandle(scm);
> >}
> >
> >But when I start this service...
> ****
> The code above is not a service. The code above is a program that installs a service, and
> the service source code is not shown, so there is no way to tell what is going wrong with
> the service. The message is certainly correct. Note that hardwiring a path to a program
> is almost invariably a Really Really Really Bad Idea; you should put it on the command
> line.
>
> Note that you did not have to write any of the above code to isntall a service; you can
> use the 'sc' program to do this. So why are you showing us the install code when it is
> clear that the error is in the service itself?
> ****
> >
> >I got error message...
> >Error 1053: Service could not respond to the start or control request
> >in a timely fashion.....
> >
> >Whats the pblem???????
> ****
> The problem almost certainly is that the program you name as the service is not by any
> stretch of the imagination a service. If you show the code for the program you think is a
> service, we will be able to tell.
>
> Note that a service, in main(), only registers the service with the SCM. And it gives the
> address of a ServiceMain. The ServiceMain will then notify the SCM with start-pending
> notifications, followed by a run-notification. It will have established the service
> control handler, and the service control handler will take care of the SCM requests,
> including pause, continue, and shutdown requests. Your service-main function will parse
> parameters if relevant and start the threads that are the service, and block until the
> service is shut down.
>
> If any of these ideas are unfamiliar, that's why your program isn't working as a service.
> A service is *not* just an ordinary C program that is run under the SCM; it is a very
> special piece of code specifically constructed to be a service.
> joe
> ****
> >Tanx to all..........
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm




Sir....
I modified the code according to this..But when I start service
exception will occur.....
Code is given below.....

#include "stdafx.h"
#include "rrmclient.h"
#include "ClientSocket.h"
#include<windows.h>
#include<stdio.h>
#include<winsvc.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;


#define SLEEP_TIME 5000

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void WINAPI ServiceMain();
void ControlHandler(DWORD request);
FILE* log;


/******************************.FUNCTION_HEADER.******************************
.Purpose :To write status to a file
.Returns :Returns integer value
.Note :
******************************************************************************/




int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
log=fopen("F:\\LOGFILE.TXT","a+");
SERVICE_TABLE_ENTRY ServiceTable[2];
//server();
ServiceTable[0].lpServiceName = "rrmclient";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;


// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);

CClientSocket Obj; //Object of class CClientSocket
CClientSocket();
Obj.InitializeClient(); //Calling the function to initialize the
client
Obj.Close(); //Function for closing the client socket
// TODO: code your application's behavior here.
}

return nRetCode;
}



/******************************.FUNCTION_HEADER.******************************
.Purpose :Main part to form a service
.Returns :Returns no value
.Note :
******************************************************************************/
void WINAPI ServiceMain()
{

ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

hStatus = RegisterServiceCtrlHandler(
"rrmclient",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{

// Registering Control Handler failed
fprintf(log,"\nRegistering Control Handler failed\n");
return;
}

SC_HANDLE schSCManager,schService;

schSCManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);

if (schSCManager == NULL)
{
fprintf(log,"OpenSCManager is failed");
}

schService=OpenService(schSCManager,"rrmclient",SERVICE_ALL_ACCESS);

if (schService == NULL)
{
fprintf(log,"OpenService is failed");
}




// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);


}





/******************************.FUNCTION_HEADER.******************************
.Purpose :To set the status of a service
.Returns :Returns no value
.Note :
******************************************************************************/


// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:


ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;

case SERVICE_CONTROL_SHUTDOWN:


ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;

default:
break;
}

// Report current status
SetServiceStatus (hStatus, &ServiceStatus);

return;
}

From: Joseph M. Newcomer on
See below...
On 9 Jan 2007 00:59:07 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:

>
>Joseph M. Newcomer wrote:
>> See below...
>>
>> On 7 Jan 2007 22:12:37 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:
>>
>> >Dear all,,,,
>> > I want to run VC program by using service....SO I wrote code for
>> >creating the service.
>> >Code is given below....
>> >
>> >void main()
>> >{
>> >SC_HANDLE myService, scm;
>> > printf("Installing RRM Service...\n");
>> > scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
>> >
>> > if (!scm)
>> > {
>> > printf("OpenSCManager fails!", GetLastError());
>> > }
>> >
>> > printf("Opened Service Control Manager...\n");
>> >
>> > myService = CreateService(
>> > scm, "rrmclient",
>> > "rrmclient",
>> > SERVICE_ALL_ACCESS,
>> > SERVICE_WIN32_OWN_PROCESS,
>> > SERVICE_DEMAND_START,
>> > SERVICE_ERROR_NORMAL,
>> > "D:\\rrmclient\\Debug\\rrmclient.exe",
>> > 0, 0, 0, 0, 0);
>> >
>> > if (!myService)
>> > {
>> > printf("CreateService fails!", GetLastError());
>> > }
>> > else
>> > {
>> > printf("Service successfully installed.\n");
>> > }
>> >
>> > CloseServiceHandle(myService);
>> > CloseServiceHandle(scm);
>> >}
>> >
>> >But when I start this service...
>> ****
>> The code above is not a service. The code above is a program that installs a service, and
>> the service source code is not shown, so there is no way to tell what is going wrong with
>> the service. The message is certainly correct. Note that hardwiring a path to a program
>> is almost invariably a Really Really Really Bad Idea; you should put it on the command
>> line.
>>
>> Note that you did not have to write any of the above code to isntall a service; you can
>> use the 'sc' program to do this. So why are you showing us the install code when it is
>> clear that the error is in the service itself?
>> ****
>> >
>> >I got error message...
>> >Error 1053: Service could not respond to the start or control request
>> >in a timely fashion.....
>> >
>> >Whats the pblem???????
>> ****
>> The problem almost certainly is that the program you name as the service is not by any
>> stretch of the imagination a service. If you show the code for the program you think is a
>> service, we will be able to tell.
>>
>> Note that a service, in main(), only registers the service with the SCM. And it gives the
>> address of a ServiceMain. The ServiceMain will then notify the SCM with start-pending
>> notifications, followed by a run-notification. It will have established the service
>> control handler, and the service control handler will take care of the SCM requests,
>> including pause, continue, and shutdown requests. Your service-main function will parse
>> parameters if relevant and start the threads that are the service, and block until the
>> service is shut down.
>>
>> If any of these ideas are unfamiliar, that's why your program isn't working as a service.
>> A service is *not* just an ordinary C program that is run under the SCM; it is a very
>> special piece of code specifically constructed to be a service.
>> joe
>> ****
>> >Tanx to all..........
>> Joseph M. Newcomer [MVP]
>> email: newcomer(a)flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
>
>
>
>
>Sir....
>I modified the code according to this..But when I start service
>exception will occur.....
>Code is given below.....
>
>#include "stdafx.h"
>#include "rrmclient.h"
>#include "ClientSocket.h"
>#include<windows.h>
>#include<stdio.h>
>#include<winsvc.h>
>#ifdef _DEBUG
>#define new DEBUG_NEW
>#endif
>
>
>// The one and only application object
>
>CWinApp theApp;
>
>using namespace std;
>
>
>#define SLEEP_TIME 5000
>
>SERVICE_STATUS ServiceStatus;
>SERVICE_STATUS_HANDLE hStatus;
>
>void WINAPI ServiceMain();
>void ControlHandler(DWORD request);
>FILE* log;
>
>
>/******************************.FUNCTION_HEADER.******************************
> .Purpose :To write status to a file
> .Returns :Returns integer value
> .Note :
> ******************************************************************************/
>
>
>
>
>int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
****
For reasons that escape explanation, the prototype for main() for a service appears to be

int _tmain()

The argc and argv are irrelevant and not used
****
>{
> int nRetCode = 0;
>
> // initialize MFC and print and error on failure
> if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
****
You should probably just pass the empty string for ::GetCommandLine because there is no
command line to the main() of a service

I have not used MFC in a service
****
> {
> // TODO: change error code to suit your needs
> _tprintf(_T("Fatal Error: MFC initialization failed\n"));
****
_tprintf is meaningless here, because there is noplace for it to print
****
> nRetCode = 1;
> }
> else
> {

> log=fopen("F:\\LOGFILE.TXT","a+");
****
I notice you do not check to see that this file opened correctly. Since a service can be
running under a restricted account, you must not assume that this will work. And
hardwiring the device path is usually a fatal mistake. For example, if F: is a network
drive, you have no reason to assume that the service can see the network drive. In fact,
it probably doesn't. So be very careful here
****
> SERVICE_TABLE_ENTRY ServiceTable[2];
> //server();
> ServiceTable[0].lpServiceName = "rrmclient";
****
That's _T("rrmclient"). Don't assume the app is ANSI.
****
> ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
> ServiceTable[1].lpServiceName = NULL;
> ServiceTable[1].lpServiceProc = NULL;
****
You could write this more simply as
SERVICE_TABLE_ENTRY ServiceTable[] = {
{_T("rrmclient"), ServiceMain},
{0, 0}
};
****
>
>
> // Start the control dispatcher thread for our service
> StartServiceCtrlDispatcher(ServiceTable);
****
Did you check the return code to see if this worked?

AT THIS POINT YOU WILL DO A 'return'. YOU WILL DO NOTHING ELSE.

At least part of the reason for the disaster is that these objects are being created int
he main() thread, which is going to disappear. You will not do any of this until you are
in the UI thread that implements the service. The main() thread is not a UI thread and
does not have a message pump! So everything from here to the end of the main() is wrong.

Sockets cannot work in this environment. There is no message pump. I notice also that
there are no error checks to see if any of this code actually did anything.
****
>
> CClientSocket Obj; //Object of class CClientSocket
> CClientSocket();
> Obj.InitializeClient(); //Calling the function to initialize the
>client
> Obj.Close(); //Function for closing the client socket
> // TODO: code your application's behavior here.
> }
>
> return nRetCode;
>}
>
>
>
>/******************************.FUNCTION_HEADER.******************************
> .Purpose :Main part to form a service
> .Returns :Returns no value
> .Note :
> ******************************************************************************/
>void WINAPI ServiceMain()
>{
>
****
Get rid of the global ServiceStatus structure. Instead, make a local variable in a
function that you call, where you pass in the variable parameters, such as the current
state, the exit code, the service exit code, and the checkpoint value.
*****
> ServiceStatus.dwServiceType = SERVICE_WIN32;
> ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
> ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
>SERVICE_ACCEPT_SHUTDOWN;
> ServiceStatus.dwWin32ExitCode = 0;
> ServiceStatus.dwServiceSpecificExitCode = 0;
> ServiceStatus.dwCheckPoint = 0;
> ServiceStatus.dwWaitHint = 0;
>
> hStatus = RegisterServiceCtrlHandler(
> "rrmclient",
> (LPHANDLER_FUNCTION)ControlHandler);
> if (hStatus == (SERVICE_STATUS_HANDLE)0)
****
if(hStatus == NULL)
****
> {
>
> // Registering Control Handler failed
> fprintf(log,"\nRegistering Control Handler failed\n");
****
Wrong. You don't even know the log file exists. You should not open it until it is
needed, and then you open it, write to it, and close it IMMEDIATELY. You did not check to
see if the log handle is NULL, and it might be. This would certainly crash your service
with an access fault. Trust nothing. Trust no one. Check, and double check, everything.

Here is a log subroutine:

void WriteLog(const CString & msg)
{
FILE * log = _ftopen(LOGFILENAME, _T("a+");
if(log == NULL)
return;
// typically you will write a timestamp here, e.g., "23-Mar-07 11:42:22"
_ftputs(msg, log);
fclose(log);
}

If you do not close after each write, you hvae no guarantee that if the service crashes
the logfile is left intact with all the data you think should be in it actually there.
****
> return;
> }
>
> SC_HANDLE schSCManager,schService;
****
Never use commas in declaration lists. One variable, one line.
****
>
> schSCManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
>
> if (schSCManager == NULL)
> {
> fprintf(log,"OpenSCManager is failed");
> }
****
None of this code makes sense in a service. The service is already created. Lose it
****
>
> schService=OpenService(schSCManager,"rrmclient",SERVICE_ALL_ACCESS);
>
> if (schService == NULL)
> {
> fprintf(log,"OpenService is failed");
> }
****
The above code makes no sense in a service. Lose it
****
>
>
>
>
> // We report the running status to SCM.
> ServiceStatus.dwCurrentState = SERVICE_RUNNING;
> SetServiceStatus (hStatus, &ServiceStatus);
****
Yes, you will do this right before doing the WaitForSingleObject call.
****
>
****
WRONG! As soon as this ServiceMain exits, your service is dead. Dead, dead, dead.

ServiceMain should do an AfxBeginThread on a UI thread. This UI thread will create any
sockets it wants and communicate on them. ServiceMain, having done all the required
setup, will then block on a Event, waiting for shutdown.

shutdown = ::CreateEvent(NULL, TRUE, FALSE, NULL); // manual-reset, non-signaled
::WaitForSingleObject(shutdown, INFINITE);
...do thread shutdown here. Note that this may require waiting for
...the thread to terminate, during which you must send STOP_PENDING requests
...at suitable intervals

>
>}
>
>
>
>
>
>/******************************.FUNCTION_HEADER.******************************
> .Purpose :To set the status of a service
> .Returns :Returns no value
> .Note :
>******************************************************************************/
>
>
>// Control handler function
>void ControlHandler(DWORD request)
>{
> switch(request)
> {
> case SERVICE_CONTROL_STOP:
>
>
> ServiceStatus.dwWin32ExitCode = 0;
> ServiceStatus.dwCurrentState = SERVICE_STOPPED;
> SetServiceStatus (hStatus, &ServiceStatus);
****
This is where you SetEvent on that event that is blocking ServiceMain. Note that you have
also done nothing to actually terminate the service, such as stopping any running threads,
so you can't claim SERVICE_STOPPED at this point. The best you can do is
SERVICE_STOP_PENDING, and you will not do SERVICE_STOPPED until you know the service has
stopped, and continual STOP_PENDING notifications will be sent by your ServiceMain thread
until it actually shuts everything down. Then you will send the SERVICE_STOPPED. Not
before that.
****
> return;
>
> case SERVICE_CONTROL_SHUTDOWN:
>
>
> ServiceStatus.dwWin32ExitCode = 0;
> ServiceStatus.dwCurrentState = SERVICE_STOPPED;
> SetServiceStatus (hStatus, &ServiceStatus);
> return;
****
Typically, you have to do nothing here, because the SERVICE_STOP request will precede the
shutdown request.
****
>
> default:
> break;
> }
>
****
What about SERVICE_CONTROL_PAUSE? SERVICE_CONTROL_CONTINUE? SERVICE_CONTROL_INTERROGATE?
And if none of the above cases are handled, exactly what status are you going to report?
Whatever trash was left in the local variable from the last report?
****
> // Report current status
> SetServiceStatus (hStatus, &ServiceStatus);
>
> return;
>}
****
The above code is not a service. You will have to add code to make it a service. Since
everything I described and more is actually documented in the MSDN, I suggest you study
the articles on how to write a service and the sample service code they illustrate. Note
that modern services will use RegisterWaitForSingleObject instead of the code I showed.
But this is all covered in the documentation. Read it.
joe
****
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: meenu on

Joseph M. Newcomer wrote:
> See below...
> On 9 Jan 2007 00:59:07 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:
>
> >
> >Joseph M. Newcomer wrote:
> >> See below...
> >>
> >> On 7 Jan 2007 22:12:37 -0800, "meenu" <mnair.lekshmi(a)gmail.com> wrote:
> >>
> >> >Dear all,,,,
> >> > I want to run VC program by using service....SO I wrote code for
> >> >creating the service.
> >> >Code is given below....
> >> >
> >> >void main()
> >> >{
> >> >SC_HANDLE myService, scm;
> >> > printf("Installing RRM Service...\n");
> >> > scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
> >> >
> >> > if (!scm)
> >> > {
> >> > printf("OpenSCManager fails!", GetLastError());
> >> > }
> >> >
> >> > printf("Opened Service Control Manager...\n");
> >> >
> >> > myService = CreateService(
> >> > scm, "rrmclient",
> >> > "rrmclient",
> >> > SERVICE_ALL_ACCESS,
> >> > SERVICE_WIN32_OWN_PROCESS,
> >> > SERVICE_DEMAND_START,
> >> > SERVICE_ERROR_NORMAL,
> >> > "D:\\rrmclient\\Debug\\rrmclient.exe",
> >> > 0, 0, 0, 0, 0);
> >> >
> >> > if (!myService)
> >> > {
> >> > printf("CreateService fails!", GetLastError());
> >> > }
> >> > else
> >> > {
> >> > printf("Service successfully installed.\n");
> >> > }
> >> >
> >> > CloseServiceHandle(myService);
> >> > CloseServiceHandle(scm);
> >> >}
> >> >
> >> >But when I start this service...
> >> ****
> >> The code above is not a service. The code above is a program that installs a service, and
> >> the service source code is not shown, so there is no way to tell what is going wrong with
> >> the service. The message is certainly correct. Note that hardwiring a path to a program
> >> is almost invariably a Really Really Really Bad Idea; you should put it on the command
> >> line.
> >>
> >> Note that you did not have to write any of the above code to isntall a service; you can
> >> use the 'sc' program to do this. So why are you showing us the install code when it is
> >> clear that the error is in the service itself?
> >> ****
> >> >
> >> >I got error message...
> >> >Error 1053: Service could not respond to the start or control request
> >> >in a timely fashion.....
> >> >
> >> >Whats the pblem???????
> >> ****
> >> The problem almost certainly is that the program you name as the service is not by any
> >> stretch of the imagination a service. If you show the code for the program you think is a
> >> service, we will be able to tell.
> >>
> >> Note that a service, in main(), only registers the service with the SCM. And it gives the
> >> address of a ServiceMain. The ServiceMain will then notify the SCM with start-pending
> >> notifications, followed by a run-notification. It will have established the service
> >> control handler, and the service control handler will take care of the SCM requests,
> >> including pause, continue, and shutdown requests. Your service-main function will parse
> >> parameters if relevant and start the threads that are the service, and block until the
> >> service is shut down.
> >>
> >> If any of these ideas are unfamiliar, that's why your program isn't working as a service.
> >> A service is *not* just an ordinary C program that is run under the SCM; it is a very
> >> special piece of code specifically constructed to be a service.
> >> joe
> >> ****
> >> >Tanx to all..........
> >> Joseph M. Newcomer [MVP]
> >> email: newcomer(a)flounder.com
> >> Web: http://www.flounder.com
> >> MVP Tips: http://www.flounder.com/mvp_tips.htm
> >
> >
> >
> >
> >Sir....
> >I modified the code according to this..But when I start service
> >exception will occur.....
> >Code is given below.....
> >
> >#include "stdafx.h"
> >#include "rrmclient.h"
> >#include "ClientSocket.h"
> >#include<windows.h>
> >#include<stdio.h>
> >#include<winsvc.h>
> >#ifdef _DEBUG
> >#define new DEBUG_NEW
> >#endif
> >
> >
> >// The one and only application object
> >
> >CWinApp theApp;
> >
> >using namespace std;
> >
> >
> >#define SLEEP_TIME 5000
> >
> >SERVICE_STATUS ServiceStatus;
> >SERVICE_STATUS_HANDLE hStatus;
> >
> >void WINAPI ServiceMain();
> >void ControlHandler(DWORD request);
> >FILE* log;
> >
> >
> >/******************************.FUNCTION_HEADER.******************************
> > .Purpose :To write status to a file
> > .Returns :Returns integer value
> > .Note :
> > ******************************************************************************/
> >
> >
> >
> >
> >int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> ****
> For reasons that escape explanation, the prototype for main() for a service appears to be
>
> int _tmain()
>
> The argc and argv are irrelevant and not used
> ****
> >{
> > int nRetCode = 0;
> >
> > // initialize MFC and print and error on failure
> > if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
> ****
> You should probably just pass the empty string for ::GetCommandLine because there is no
> command line to the main() of a service
>
> I have not used MFC in a service
> ****
> > {
> > // TODO: change error code to suit your needs
> > _tprintf(_T("Fatal Error: MFC initialization failed\n"));
> ****
> _tprintf is meaningless here, because there is noplace for it to print
> ****
> > nRetCode = 1;
> > }
> > else
> > {
>
> > log=fopen("F:\\LOGFILE.TXT","a+");
> ****
> I notice you do not check to see that this file opened correctly. Since a service can be
> running under a restricted account, you must not assume that this will work. And
> hardwiring the device path is usually a fatal mistake. For example, if F: is a network
> drive, you have no reason to assume that the service can see the network drive. In fact,
> it probably doesn't. So be very careful here
> ****
> > SERVICE_TABLE_ENTRY ServiceTable[2];
> > //server();
> > ServiceTable[0].lpServiceName = "rrmclient";
> ****
> That's _T("rrmclient"). Don't assume the app is ANSI.
> ****
> > ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
> > ServiceTable[1].lpServiceName = NULL;
> > ServiceTable[1].lpServiceProc = NULL;
> ****
> You could write this more simply as
> SERVICE_TABLE_ENTRY ServiceTable[] = {
> {_T("rrmclient"), ServiceMain},
> {0, 0}
> };
> ****
> >
> >
> > // Start the control dispatcher thread for our service
> > StartServiceCtrlDispatcher(ServiceTable);
> ****
> Did you check the return code to see if this worked?
>
> AT THIS POINT YOU WILL DO A 'return'. YOU WILL DO NOTHING ELSE.
>
> At least part of the reason for the disaster is that these objects are being created int
> he main() thread, which is going to disappear. You will not do any of this until you are
> in the UI thread that implements the service. The main() thread is not a UI thread and
> does not have a message pump! So everything from here to the end of the main() is wrong.
>
> Sockets cannot work in this environment. There is no message pump. I notice also that
> there are no error checks to see if any of this code actually did anything.
> ****
> >
> > CClientSocket Obj; //Object of class CClientSocket
> > CClientSocket();
> > Obj.InitializeClient(); //Calling the function to initialize the
> >client
> > Obj.Close(); //Function for closing the client socket
> > // TODO: code your application's behavior here.
> > }
> >
> > return nRetCode;
> >}
> >
> >
> >
> >/******************************.FUNCTION_HEADER.******************************
> > .Purpose :Main part to form a service
> > .Returns :Returns no value
> > .Note :
> > ******************************************************************************/
> >void WINAPI ServiceMain()
> >{
> >
> ****
> Get rid of the global ServiceStatus structure. Instead, make a local variable in a
> function that you call, where you pass in the variable parameters, such as the current
> state, the exit code, the service exit code, and the checkpoint value.
> *****
> > ServiceStatus.dwServiceType = SERVICE_WIN32;
> > ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
> > ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
> >SERVICE_ACCEPT_SHUTDOWN;
> > ServiceStatus.dwWin32ExitCode = 0;
> > ServiceStatus.dwServiceSpecificExitCode = 0;
> > ServiceStatus.dwCheckPoint = 0;
> > ServiceStatus.dwWaitHint = 0;
> >
> > hStatus = RegisterServiceCtrlHandler(
> > "rrmclient",
> > (LPHANDLER_FUNCTION)ControlHandler);
> > if (hStatus == (SERVICE_STATUS_HANDLE)0)
> ****
> if(hStatus == NULL)
> ****
> > {
> >
> > // Registering Control Handler failed
> > fprintf(log,"\nRegistering Control Handler failed\n");
> ****
> Wrong. You don't even know the log file exists. You should not open it until it is
> needed, and then you open it, write to it, and close it IMMEDIATELY. You did not check to
> see if the log handle is NULL, and it might be. This would certainly crash your service
> with an access fault. Trust nothing. Trust no one. Check, and double check, everything.
>
> Here is a log subroutine:
>
> void WriteLog(const CString & msg)
> {
> FILE * log = _ftopen(LOGFILENAME, _T("a+");
> if(log == NULL)
> return;
> // typically you will write a timestamp here, e.g., "23-Mar-07 11:42:22"
> _ftputs(msg, log);
> fclose(log);
> }
>
> If you do not close after each write, you hvae no guarantee that if the service crashes
> the logfile is left intact with all the data you think should be in it actually there.
> ****
> > return;
> > }
> >
> > SC_HANDLE schSCManager,schService;
> ****
> Never use commas in declaration lists. One variable, one line.
> ****
> >
> > schSCManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
> >
> > if (schSCManager == NULL)
> > {
> > fprintf(log,"OpenSCManager is failed");
> > }
> ****
> None of this code makes sense in a service. The service is already created. Lose it
> ****
> >
> > schService=OpenService(schSCManager,"rrmclient",SERVICE_ALL_ACCESS);
> >
> > if (schService == NULL)
> > {
> > fprintf(log,"OpenService is failed");
> > }
> ****
> The above code makes no sense in a service. Lose it
> ****
> >
> >
> >
> >
> > // We report the running status to SCM.
> > ServiceStatus.dwCurrentState = SERVICE_RUNNING;
> > SetServiceStatus (hStatus, &ServiceStatus);
> ****
> Yes, you will do this right before doing the WaitForSingleObject call.
> ****
> >
> ****
> WRONG! As soon as this ServiceMain exits, your service is dead. Dead, dead, dead.
>
> ServiceMain should do an AfxBeginThread on a UI thread. This UI thread will create any
> sockets it wants and communicate on them. ServiceMain, having done all the required
> setup, will then block on a Event, waiting for shutdown.
>
> shutdown = ::CreateEvent(NULL, TRUE, FALSE, NULL); // manual-reset, non-signaled
> ::WaitForSingleObject(shutdown, INFINITE);
> ...do thread shutdown here. Note that this may require waiting for
> ...the thread to terminate, during which you must send STOP_PENDING requests
> ...at suitable intervals
>
> >
> >}
> >
> >
> >
> >
> >
> >/******************************.FUNCTION_HEADER.******************************
> > .Purpose :To set the status of a service
> > .Returns :Returns no value
> > .Note :
> >******************************************************************************/
> >
> >
> >// Control handler function
> >void ControlHandler(DWORD request)
> >{
> > switch(request)
> > {
> > case SERVICE_CONTROL_STOP:
> >
> >
> > ServiceStatus.dwWin32ExitCode = 0;
> > ServiceStatus.dwCurrentState = SERVICE_STOPPED;
> > SetServiceStatus (hStatus, &ServiceStatus);
> ****
> This is where you SetEvent on that event that is blocking ServiceMain. Note that you have
> also done nothing to actually terminate the service, such as stopping any running threads,
> so you can't claim SERVICE_STOPPED at this point. The best you can do is
> SERVICE_STOP_PENDING, and you will not do SERVICE_STOPPED until you know the service has
> stopped, and continual STOP_PENDING notifications will be sent by your ServiceMain thread
> until it actually shuts everything down. Then you will send the SERVICE_STOPPED. Not
> before that.
> ****
> > return;
> >
> > case SERVICE_CONTROL_SHUTDOWN:
> >
> >
> > ServiceStatus.dwWin32ExitCode = 0;
> > ServiceStatus.dwCurrentState = SERVICE_STOPPED;
> > SetServiceStatus (hStatus, &ServiceStatus);
> > return;
> ****
> Typically, you have to do nothing here, because the SERVICE_STOP request will precede the
> shutdown request.
> ****
> >
> > default:
> > break;
> > }
> >
> ****
> What about SERVICE_CONTROL_PAUSE? SERVICE_CONTROL_CONTINUE? SERVICE_CONTROL_INTERROGATE?
> And if none of the above cases are handled, exactly what status are you going to report?
> Whatever trash was left in the local variable from the last report?
> ****
> > // Report current status
> > SetServiceStatus (hStatus, &ServiceStatus);
> >
> > return;
> >}
> ****
> The above code is not a service. You will have to add code to make it a service. Since
> everything I described and more is actually documented in the MSDN, I suggest you study
> the articles on how to write a service and the sample service code they illustrate. Note
> that modern services will use RegisterWaitForSingleObject instead of the code I showed.
> But this is all covered in the documentation. Read it.
> joe
> ****
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm


OK...sir..thanx a lot..