Click to See Complete Forum and Search --> : Problems in stopping the Windows Service


ujjwal_rp
April 21st, 2003, 02:30 AM
Hello,

I'm trying to write a service in VC++. My service should call one executable program. The program runs in infinite loop. I am able to start the exe through service. But how do i stop it?
I m trying to run the exe in a separate thread. But when service starts after some time it kills itself along with the child thread in which program runs. Do i need to execute the exe synchronously (using ::system("program path") or asynchronously (either using thread or using CreateProcess) ?. I also tried CreateProcess. But while stopping the service if i use TerminateProcess, I get errorcode = 5, which means access denied.

I m new to Windows SDK . Can anybody show me the way ???

-- Ujjwal

mahanare
April 21st, 2003, 04:43 AM
UJJWAL,
do onething.

You want to run an .exe in infinite loop, right.
If that is right, then, make the exe as service, once you make it service, then you can start it through program, and stop the service also.
so, when you stop service, this means that you r closing your .exe.
so try with this view, it may help you,

post your reply on this so that any other guru may help u

sincerely
mahanare

ujjwal_rp
April 21st, 2003, 05:00 AM
Dear mahanare,

Initially I was trying that, but the problem is, the sample of service I m trying is Non-MFC and the content of my code uses MFC stuff. The program is a simple server program, which keeps waiting for the client. When client connects, server approves the request and lets client to proceed. I wrote a simple exe program in which server waits infinitely for the client.
When I tried to combine both (Service and MyServer) the programs, compiler gives me conflicts. i.e. when I link it with MFC libraries, Service doesn't compile it throws errors like "error LNK2001: unresolved external symbol __imp__EqualSid@8". Finally I decided to run them separatley.

I need ur opinion on this. Or is there any work around ? Keep me posted.

Thanks n regards,
-- Ujjwal

mahanare
April 21st, 2003, 05:30 AM
Ujjwal, I got confused,
this is what i understood.
You wrote one application (MyServer) which waits for the client to cotact it right!
your" MyServer" has to be in in wait state.
if this is right,
then What is the complexity you r getting in making your application a service.


// Open a handle to the SC Manager database.
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (schSCManager == NULL)
MyErrorExit("OpenSCManager");



The above code block returns you one handle of type SC_HANDLE
right.
now if your service diplay name is
LPCTSTR lpszDisplayname="UjjwalService";



LPCTSTR lpszBinaryPathName ="D:\\MyServer.exe" ;


schService = CreateService(
schSCManager, // SCManager database
"Ujjwal_Service", // name of service
lpszDisplayName, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
lpszBinaryPathName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password

if (schService == NULL)
{
//write your own error handling..
MyErrorExit("CreateService");
else
printf("CreateService SUCCESS.\n");

}


so the above code gives you idea about how to make your .exe a service.
Now as you already know how to open SCManager using openSCManager() function, which returns a handle of type SC_HANDLE
use this handle to start service

All the code i am giving is from MSDN only.
now see the following function how it is starting service.


DWORD StartSampleService()
{
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwStatus;

schService = OpenService(
schSCManager, // SCM database
"Sample_Srv", // service name
SERVICE_ALL_ACCESS);

if (schService == NULL)
{
MyErrorExit("OpenService");
}

if (!StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
MyErrorExit("StartService");
}
else
{
printf("Service start pending.\n");
}

// Check the status until the service is no longer start pending.

if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of status information structure
{
MyErrorExit("QueryServiceStatus");
}

// Save the tick count and initial checkpoint.

dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;

while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.

dwWaitTime = ssStatus.dwWaitHint / 10;

if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;

Sleep( dwWaitTime );

// Check the status again.

if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of structure
break;

if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.

dwStartTickCount = GetTickCount():
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}

if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("StartService SUCCESS.\n");
dwStatus = NO_ERROR;
}
else
{
printf("\nService not started. \n");
printf(" Current State: %d\n", ssStatus.dwCurrentState);
printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode);
printf(" Service Specific Exit Code: %d\n",
ssStatus.dwServiceSpecificExitCode);
printf(" Check Point: %d\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %d\n", ssStatus.dwWaitHint);
dwStatus = GetLastError();
}

CloseServiceHandle(schService);
return dwStatus;
}



when you want to stop a service use the following function


BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);



Did i understand you in wrong way????
Do let me know your reaction.

cheers
mahanare

mahanare
April 21st, 2003, 05:35 AM
read MSDN carefully to understand the parameters etc.
I never remember anthing in vc, just go thru MSDN ( i remember how to go to the required function etc) and read the help and use the function.

one more thing is "once you prepared an .exe irrespective of whether it uses MFC or it is non-MFC you can make it service. there is no harm in that, i feel"

best wishes for ur programming.

cheers
mahanare

ujjwal_rp
April 21st, 2003, 08:19 AM
Hello,

You understood correctly. I want to run MyServer.exe as a service. As u mentioned, I used OpenSCManager and CreateService function to register MyServer.exe as service. It appears in Control Panel Services. But when I try to start the same (either through control panel or through program) it throws me error 1053:The service did not respond to the start or control request in a timely fashion.

Also for removal of service. I wrote the function..

int RemoveMyService() {

schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (schSCManager == NULL)
cout<<"OpenSCManager Failed\n";


schService = OpenService(
schSCManager, // SCM database
ServiceName, // service name
DELETE);

if (schService == NULL) {
cout<<"OpenService Failed\n";
CloseServiceHandle(schSCManager);
return -1;
}


if( ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus) ) {
cout<<"Stopping Service\n";
Sleep(1000);

while( QueryServiceStatus(schService, &ssStatus) ) {
if( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
cout<<".";
Sleep( 1000 );
} else
break;
}

if( ssStatus.dwCurrentState == SERVICE_STOPPED )
cout<<"Service Stopped\n";
else {
cout<<"Failed to stop the service\n";
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return -1;
}

}


BOOL Retval = DeleteService(schService);
if (Retval == 0) {
cout<<"Can't Delete service\n";
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return -1;
}

CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);

return 0;

}

But instead of removing it directly it marks it for the deletion, though I am closing all the handles. I , not able to delete it completely unless i restart the m/c.

mahanare
April 21st, 2003, 09:12 AM
it is really interesting to know about 1053 error. is there any progress.
regarding removing service... I feel the following may be a reason.
service is a part of the O.S.right. so when u are delating it, it is marking for delation and next time when u reboot your m/c it is atomatically delated."
"But i strongly feel that there should be some mechanism to delete the service when we want to do" may be it is not possible.

Why do u want to delete the service?
use "ControlService()" to stop the service.
see installing the service, and removing the service are extreme steps which we do only when it is necessary.
to start the service we have got one function as u know it is "StartService",
actually i was thinking that there is a function like stopService(), but i didn't find it. The function ControlService() will do lot of works (stop, restart, etc,, of the service) depending upon the parameter.

so use DeleteService() only when u want to delete the service from services.
I worked only for some extent and i wrote small article in codeguru alos on this (how to start a windows xp service)
But with discussions with u and some other guys on codeguru i am really learning a lot.

it is nice to see you working on service.
keep posting on codeguru your results, and if you feel anything you "discovered" in learning process, is fit for sharing with others.
do share it.
knowledge grows when we share it, shrinks when we hide it.

cheers
mahanare

Mick
April 21st, 2003, 05:05 PM
Originally posted by ujjwal_rp
Hello,

You understood correctly. I want to run MyServer.exe as a service. As u mentioned, I used OpenSCManager and CreateService function to register MyServer.exe as service. It appears in Control Panel Services. But when I try to start the same (either through control panel or through program) it throws me error 1053:The service did not respond to the start or control request in a timely fashion.



Are you using SetServiceStatus(...) correctly? Generally that error indicates your not setting the service status, and the Service Control Manger declares your service hung.

muthuis
April 22nd, 2003, 05:52 AM
I think u are mistaken. I have a question on this.
Is it possible to convert a normal executable into an NT Service, just by passing its path to CreateService function? I don't think it is possible. Please correct me if I am wrong.

An NT service is supposed to have a ServiceControlHandler which receives the requests for SERVICE_START/STOP/PAUSE/ CONTINUE etc., requests.

A regular executable does not possess any of such characteristics. So I don't think it is possible to convert a regular exe into an NT Service.

There is a program supplied by Microsoft(I am not sure who), "Srvany.exe". This converts all executables into an NT Service.

Now turning to the actual problem.
ujjwal_rp,
Why don't you try creating the service as a Win32 application and use MFC libraries?

The best alternative will be to use Console project and Winsock without MFC.

ujjwal_rp
April 22nd, 2003, 05:58 AM
As per Mr. mahanare's suggestion, I can register an exe file (here MyServer.exe) to run as service using CreateService. Here I am assigning the path of MyServer.exe to the variable LPCTSTR lpBinaryPathName.

So I am not embedding the code of MyServer.exe inside a service program. This Myserver.exe gets registered properly, it does appear in a control panel. But as i mentioned earlier, I get error 1053 when i start it either using control panel or through program.

Though I m not embedding the code (of Myserver) in side my service do i need to use the functions like SetServiceStatus(), RegisterServiceCtrlHandlerEx etc. Again is ServiceMain() function necessary ? becoz now my service is pointing to Myserver.exe. and not the actual service program executable. So whatever functions I write in ServiceMain(), i think they wont be of any use... (:confused: )...

I need ur opinion...

mahanare
April 22nd, 2003, 07:12 AM
muthu we can convert an .exe file to service.
U need not have any doubts about that, I feel,
correct me if I am wrong.
within a week i want to do some application related to start, create stop etc of a service.
then i will let u know more about this.
but already i did some work on this, and i feel there is no obstacle in converting an .exe to a service.
well, whether u do is using normal console or MFC application it doesn't matter as we have to use the standard API functions.
see go through this discussion from the beginning. I wrote clearly how to do everything even ujjwal did good job.
o.k



cheers
mahanare

ujjwal_rp
April 22nd, 2003, 10:59 AM
Hello,

Finally I couldn't get what went wrong in converting an exe to service, I again went back and thought of writing everything in one code instead of making Myserver.exe as service. As I mentioned earlier, while doing this I got so many errors like

"error LNK2001: unresolved external symbol __imp__EqualSid@8"

fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h>. and so on..

As a workaround, you have make little changes in StdAfx.h file.
include <afxwin.h> at the top.... as..

#if !defined(AFX_STDAFX_H__8C0B745A_43A0_45E0_AF4B_515F39277EA3__INCLUDED_)
#define AFX_STDAFX_H__8C0B745A_43A0_45E0_AF4B_515F39277EA3__INCLUDED_

#include <afxwin.h> //Add here

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//#define STRICT

and remove the macro definition #define STRICT as shown.

This way I eliminated the errors. n service is working fine now.
But I'm still expecting a solution for making exe as service on the forum..

mahanare
April 22nd, 2003, 12:41 PM
Ujjwal,
can u attach the code u worked out as a zip in codeguru.
or send me a email.
Because surprisingly i am also getting same error when i tried to start a service. error: 1053 interesting.
actually i am planning to write a console application to start delete stop and and create a service with user inputs.
creating service is o.k and delating service... yah it is marking for delation and doing it only when u restart m/c.

when i tried to start my own service i am getting 1053 but when i tried to work with standard service like winmgmt etc.
it didn't give problem.
so I am searching for solution. it seems there is problem in creating service itself.
well, I am trying to do something.
But mean while if wouldn't mind give me the code u did, if u wouldn't mind.

bye
harinath

mahanare
April 23rd, 2003, 12:47 AM
Hi, Ujjwal, I i got rid of that 1053 error.
It was my own blunder to just use MSDN code.

we have to set the service as interactive also.
so just a minor modification in the code, it will work that's all, I think

SC_HANDLE schService;
schService = CreateService(
schSCManager, // SCManager database
lpszServiceName, // name of service
lpszDisplayName, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS| SERVICE_INTERACTIVE_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
lpszBinaryPathName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password

still now i used only. win32_OWN_PROCESS but as my service needs interaction with desktop so I need to use the following as 5th parameter, ujjwal u try this and tell me whether it is working or not.

SERVICE_WIN32_OWN_PROCESS| SERVICE_INTERACTIVE_PROCESS, // service type

we may need to add more to this using "|" i think.
let us try this aspect.

cheers
harinath

ujjwal_rp
April 23rd, 2003, 04:00 AM
Hello Mr. Mahanare,

Yes, Service works if we pass

SERVICE_WIN32_OWN_PROCESS| SERVICE_INTERACTIVE_PROCESS,

these parameters to CreateService. But SERVICE_INTERACTIVE_PROCESS is same as to allow service to interact with desktop. If u pass this additional parameter, in Service properties -> LogOn->LocalSytemAccount you'll find that the check box "Allow service to interact with desktop" gets checked automatically. I've downloaded some tips regarding creation of a service by Jeffrey Richter . You can find it a attachment.

mahanare
April 25th, 2003, 01:04 PM
Hi, Ujjwal, Nice to see your work and good attachment.
yah. it really gave good insight into service.
I didn't go through it fully as i was working with some other function (CreateProcessAsUser()).
well, for me service was working partially.
i wrote a simple console application recently with a menu to create, start, stop, delete etc of services.
creating is working and delating is also working.
starting is working partially.
i have any simple .exe file called "AddIcon.exe" to put a icon in the system tray. so i made this a service, well, when i start the service either through my program or manually, i can see icon in the tray ( it means service is started) but the status of the service is remaining as "starting" so SCM is waiting for it, and after 1 or 2 minutes, it is again giving the "timely" error.
well, if you have any ideas abt this u can share.

I read somewhere else, we have to set the status of service so that SCM wouldn't close the service feeling that it didn't succeded in starting.

well, this weekend i want to be work free so i will try next week some time on this.

have nice time

cheers
mahanare

Mick
April 25th, 2003, 03:58 PM
Originally posted by mahanare
Hi, Ujjwal, Nice to see your work and good attachment.
yah. it really gave good insight into service.
I didn't go through it fully as i was working with some other function (CreateProcessAsUser()).
well, for me service was working partially.
i wrote a simple console application recently with a menu to create, start, stop, delete etc of services.
creating is working and delating is also working.
starting is working partially.
i have any simple .exe file called "AddIcon.exe" to put a icon in the system tray. so i made this a service, well, when i start the service either through my program or manually, i can see icon in the tray ( it means service is started) but the status of the service is remaining as "starting" so SCM is waiting for it, and after 1 or 2 minutes, it is again giving the "timely" error.
well, if you have any ideas abt this u can share.

I read somewhere else, we have to set the status of service so that SCM wouldn't close the service feeling that it didn't succeded in starting.

well, this weekend i want to be work free so i will try next week some time on this.

have nice time

cheers
mahanare

mahanare, I responded to your PM, if you still can't get it working, or don't understand what I said, then if you can, post your project (stripped down showing the problem if you can) zipped up here, and I'll be more than happy to take a look and see what's wrong.

mahanare
April 26th, 2003, 01:02 AM
Hi, Mick thanks for responding to my PM.
well, ACtually I am not using service main function.
I am doing with other APIs that i found in MSDN.

my purpose of the project is this

while(1)
{
int option=0;
cout<<"\n select a choice \n";
cout<<"1.exit 2. Create a new Service, 3. Start a Service \n";
cout<<"4.Stop a Service 5.Delete a Service\n";
cin>>option;
switch(option)
{
case 2:
CreateSampleService(schSCManager);
break;
case 3:
StartSampleService(schSCManager);
break;
case 4:
StopSampleService(schSCManager);
break;
case 5:
DeleteSampleService(schSCManager);
break;
default:
cout<<" u r exiting";
cin>>option;
exit(1);
break;

}
}


I wrote functions to used in this switch case.
all are there in the zipped project.

In order to not to give trouble to you and to be clear with what I am doing here, I am attaching an .exe file that i am trying to make a service("AddIcon.exe",to put icon in the system tray)
Code u can find it in Simple_Service_Example.zip which you can find in the Simple_Service.zip which is the attachment.
It contains the full project minus the .obj and .exe files.
well, Hope You can spare some time for me.
Thanks a lot in advance.
cheers
mahanare

Mick
April 26th, 2003, 01:24 AM
Originally posted by mahanare
Hi, Mick thanks for responding to my PM.
well, ACtually I am not using service main function.
I am doing with other APIs that i found in MSDN.

my purpose of the project is this

while(1)
{
int option=0;
cout<<"\n select a choice \n";
cout<<"1.exit 2. Create a new Service, 3. Start a Service \n";
cout<<"4.Stop a Service 5.Delete a Service\n";
cin>>option;
switch(option)
{
case 2:
CreateSampleService(schSCManager);
break;
case 3:
StartSampleService(schSCManager);
break;
case 4:
StopSampleService(schSCManager);
break;
case 5:
DeleteSampleService(schSCManager);
break;
default:
cout<<" u r exiting";
cin>>option;
exit(1);
break;

}
}


I wrote functions to used in this switch case.
all are there in the zipped project.

In order to not to give trouble to you and to be clear with what I am doing here, I am attaching an .exe file that i am trying to make a service("AddIcon.exe",to put icon in the system tray)
Code u can find it in Simple_Service_Example.zip which you can find in the Simple_Service.zip which is the attachment.
It contains the full project minus the .obj and .exe files.
well, Hope You can spare some time for me.
Thanks a lot in advance.
cheers
mahanare

Just so you know...I got your zip, but I'm a happy camper right now, so tomorrow tomorrow, I love you tomorrow...opps it's today, give me a couple of hours for sleep ;) Should I sleep, but concentrating is out of the question right now :)

PS: it was friday night, it's now sat morn. need I say more :)

mahanare
April 26th, 2003, 01:40 AM
Yah.. You need sleep man.
I am in India and it is around 11 O clock in the morning.

sticking to Idiot box always is not healthy, and certainly we need a shutdown and reboot to get energies back(sleeping and waking next morning)
O.K then see you, Have nice sleep.
and GOOD NIGHT.

cheers
mahanare

Mick
April 27th, 2003, 03:17 AM
I've looked at your code. I guess my statement would be, you can't just make a serivce for an exe if it doesn't know how to talk to the SC manager. But generally you code a .exe to 'be' a service, how would some arbitrary exe respond to a SC request to stop or start????? It cant'....it has no SC handler...

mahanare
April 27th, 2003, 03:50 AM
No mick I am opening SC manager with the api function I have,


SC_HANDLE OpenSampleSCManager()
{
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (schSCManager == NULL)
{
// cstrMessage="OpenSCManager";
// MessageBox(NULL,cstrMessage,cstrCaption,NULL);
cout<<"Error code "<<GetLastError()<<endl;
}
else
return schSCManager;
}


and i am using this handle for all cases(starting,stopping of a service etc) as i wrote in the switch case

Mick
April 27th, 2003, 05:02 AM
Originally posted by mahanare
No mick I am opening SC manager with the api function I have,


SC_HANDLE OpenSampleSCManager()
{
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (schSCManager == NULL)
{
// cstrMessage="OpenSCManager";
// MessageBox(NULL,cstrMessage,cstrCaption,NULL);
cout<<"Error code "<<GetLastError()<<endl;
}
else
return schSCManager;
}


and i am using this handle for all cases(starting,stopping of a service etc) as i wrote in the switch case

Yes, but wan't the whole discussion about why when you start an .exe you get an error? The error is because it's not a 'exe' that's been coded as a service, thus it doesn't understand stop/start...I've only written services as 'services' I may be wrong, but my question stands, how would a non-service exe, know how to stop and start? or pause for that matter?

mahanare
April 27th, 2003, 05:17 AM
O.K,
I think it is possible
Even I wrote an article on how to start a service on codeguru.com

http://www.codeguru.com/system/Simple_Service_Example.html

As this article is so primitive one, so I wanted to add some stuff to it. we have good APIs to do the work.

"OpenSCManager" opens SCM manager and on success returns a handle to it.
then using "CreateService" we can create a service. my application is able to create service (may be one needs admin previlages but i worked as admin privilage but ofcourse now i am made a normal user)

for doing other works we have "OpenService()" API which returns a handle to the service. so using other APIs we can do any work on the service ( i feel excuse me if i am wrong and just 2 1/2 months old in vc++ that too self learning w/o even books)

now Even my application is able to start a service but as u said there is some misunderstanding with the SCM as the status is remaining as "starting" for ever, SCM is closing the operation.

I wanted to know what is the wrong with my code or what should more be done with this.

if i succeed in this I can update my article on our codeguru.com and even it helps me in my work in office.

you can refer to the MSDN and even to my article to clear any doubts you have.

hope this helps u to help me

cheers
mahanare

mahanare
April 27th, 2003, 05:20 AM
Mick You can guide me to good resources on how to use Servicemain() and work with services in your way of programming.
It may solve my problem i feel.

cheers
mahanare

Mick
April 27th, 2003, 08:39 PM
Originally posted by mahanare
Mick You can guide me to good resources on how to use Servicemain() and work with services in your way of programming.
It may solve my problem i feel.

cheers
mahanare

Hmm well while I was waiting for the codeguru forums to come back up, I caught up on some articles from the main page....

Here is a link (haven't looked at the code which describes what I am talking about)

http://www.codeguru.com/system/HelloService.html

Also you have the platform SDK? Install the samples...there is a service example if I recall correctly. I'm sure if you search codeguru, you can find an example of a service.

muthuis
April 27th, 2003, 08:43 PM
Hi Hari,
What Mick says is correct. A Service program needs to understand/receive the commands like SERVICE_STOP/START/ CONTINUE/PAUSE etc.,
An ordinary exe doesn't have the capability to understand this kinda commands.
What we do using

OpenSCManager
CreateService

is just to create an entry under the registry key HKLM\System\CurrentControlSet\Services\Servicename.

That's it. SC Manager picks up the entries from this place and tries sending commands. But this itself doesn't guarantee that an normal executable can understand these commands.

You can probably follow this link and understand/use the code if you like it.

http://codersource.tripod.com/win32_ntservice.html


Hope this helps.

ujjwal_rp
April 28th, 2003, 12:16 AM
Hello Hari,

I went thro' ur program. Becoz of the infinite while loop, ur service doesn't get sufficient time to start. Though ur service is starting through the program, manually it might throw the error 1053.

Try to execute ur while loop in a separate thread. This 'll eliminte the error 1053.

I'm pasting the part of ur main function. Let me know if it works.


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
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
CString strHello;
strHello.LoadString(IDS_HELLO);
cout << (LPCTSTR)strHello << endl;
}

schSCManager=OpenSampleSCManager();

HANDLE hThread = NULL;
LPDWORD dwThreadId = NULL;


hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)IconThreadProc,NULL, 0, dwThreadId);



return nRetCode;
}


DWORD WINAPI IconThreadProc(LPVOID lpParameter) {


while(1)
{
int option=0;
cout<<"\n select a choice \n";
cout<<"1.exit 2. Create a new Service, 3. Start a Service \n";
cout<<"4.Stop a Service 5.Delete a Service\n";
cin>>option;
switch(option)
{
case 2:
CreateSampleService(schSCManager);
break;
case 3:
StartSampleService(schSCManager);
break;
case 4:
StopSampleService(schSCManager);
break;
case 5:
DeleteSampleService(schSCManager);
break;
default:
cout<<" u r exiting";
cin>>option;
exit(1);
break;

}
}

return 0;
}

mahanare
April 28th, 2003, 12:21 AM
Thank you muthu,
I have saw your code. it is beatiful.
Though your logic seems good and correct.
I didn't find difference in my code and your code in creating a service.
Only difference i found is for running service you are using service main() function. yes, I found lot of difference in this regard.
Is it the part of code that is making the difference?
because I am also using Console application only.

cheers
mahanare
(harinath)

muthuis
April 28th, 2003, 02:56 AM
Well Hari! I saw ur code. Tell me if I've understood ur code rightly.

1. Your application is one which tries to do some Service Management. i.e, you are trying to start/stop/delete already available services and Create new services.

2. Your Start sample service works perfect when it starts the Proper NT service executables. But it cannot start your AddIcon because of the problems of ordinary executables' inability to handle service messages.

3. Your create service/delete service also works perfect. It creates entry for new services. But only if the created program is an NT Service, it makes sense. Otherwise, it simply creates an entry in the Registry.

Hope this helps.

mahanare
April 28th, 2003, 03:13 AM
muthu u r right.
You understood my program in the right way. Thanks a lot.

Well, If we see the normal services (system services) they are actually some .exe files only and they are made service by O.S.
I think by service we mean running the application forever(in logon state). O.K. This might be the idea of Microsoft (in parallel to linux deamons).

But still I ask one thing why is not possible to make a .exe to a service? Does an .exe needs something else to be made service.

There should be some way of doing the work done, might be few lines of code, which handle the SCM. I am wondering what to do Now!

well, if possible try to solve my problem..... I am not getting any ideas, as you already did good work on this, u can help me, i feel.
as i am newbie to vc and i am just using MSDN to work, even without any books.

Hope i get my problem in some way or other.
thanks for the care you showed towards my application

cheers
mahanare

muthuis
April 28th, 2003, 03:57 AM
Your observation about this is right. Ofcourse an NT Service is also an executable. But all executables are not meant to be NT services.
I think there is a program called "srvany.exe" which has the capability to convert a normal exe into an NT service. If possible try to get it and then convert this application into an NT Service, though it is not really an advisable method.
The best thing for you will be to write a new NT service program, with the required functionality. May be you can try writing your code as some modular functions and then use them in ur program.

Mick
April 28th, 2003, 04:15 AM
Originally posted by muthuis
Your observation about this is right. Ofcourse an NT Service is also an executable. But all executables are not meant to be NT services.
I think there is a program called "srvany.exe" which has the capability to convert a normal exe into an NT service. If possible try to get it and then convert this application into an NT Service, though it is not really an advisable method.
The best thing for you will be to write a new NT service program, with the required functionality. May be you can try writing your code as some modular functions and then use them in ur program.

While I have never used srvany, nor err umm RE'd it. I would imagine it has all the required SC functions, and just starts the passed progarm as a process, when it gets a SERVICE_CONTROL_STOP just calls terminateprocess using the created processes handle, that's just my guess. Calling terminateprocess as you know isn't the best thing to do, since it doesn't give the prog a chance to clean up on exit. So I agree with you the best thing to do is to write your own service.

mahanare
April 28th, 2003, 04:26 AM
Ummm. It is o.k, I will try it in other way (the way u did)
but still I am not sure why my app is not working.
actually even my app is able to start the service (addicon.exe) but the problem is it is not able to set the status properly, so SCM is closing the service as the status is remaining in "starting".
Isn't it trying other way is running away from the original problem?

O.K let it be thanks a lot for ur attention.

cheers
mahanare

mahanare
April 28th, 2003, 07:57 AM
Hi Muthu and Mick.
is the following code acceptable for starting service? i got it from MSDN. I didn't test it.
hope u reply me
thanks in advance
cheers
mahanare

SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;

VOID MyServiceStart (DWORD argc, LPTSTR *argv);
VOID MyServiceCtrlHandler (DWORD opcode);
DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv,
DWORD *specificError);

void main( )
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ "MyService", MyServiceStart },
{ NULL, NULL }
};

if (!StartServiceCtrlDispatcher( DispatchTable))
{
SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error =
%d\n", GetLastError());
}
}

VOID SvcDebugOut(LPSTR String, DWORD Status)
{
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
}
}



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

MyServiceStatus.dwServiceType = SERVICE_WIN32;
MyServiceStatus.dwCurrentState = SERVICE_START_PENDING;
MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwServiceSpecificExitCode = 0;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

MyServiceStatusHandle = RegisterServiceCtrlHandler(
"MyService",
MyServiceCtrlHandler);

if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler
failed %d\n", GetLastError());
return;
}

// Initialization code goes here.
status = MyServiceInitialization(argc,argv, &specificError);

// Handle error condition
if (status != NO_ERROR)
{
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
MyServiceStatus.dwWin32ExitCode = status;
MyServiceStatus.dwServiceSpecificExitCode = specificError;

SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
return;
}

// Initialization complete - report running status.
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
%ld\n",status);
}

// This is where the service does its work.
SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0);

return;
}

// Stub initialization function.
DWORD MyServiceInitialization(DWORD argc, LPTSTR *argv,
DWORD *specificError)
{
argv;
argc;
specificError;
return(0);
}

mahanare
April 28th, 2003, 08:09 AM
Originally posted by ujjwal_rp
Hello Hari,

I went thro' ur program. Becoz of the infinite while loop, ur service doesn't get sufficient time to start. Though ur service is starting through the program, manually it might throw the error 1053.

Try to execute ur while loop in a separate thread. This 'll eliminte the error 1053.

I'm pasting the part of ur main function. Let me know if it works.



thank you ujjwal, I will try your code. actually as the our discussion thread spawned into many pages I missed to read your post, I am sorry about that.
well, I should tell you one thing, whether i started manually or programmatically i am getting the same error, it is starting the service and giving 1053 error(closing the service)
thanks for ur attempt.
Now i lost my administrative previlages so I may not be able to check this immediately. when i come up with some result i will let u know.

cheers
mahanare

muthuis
April 29th, 2003, 01:58 AM
You've declared

MyServiceCtrlHandler


but didn't give any definition.

mahanare
April 29th, 2003, 03:45 AM
Hi, Muthu.
actually all the code i am giving is from MSDN only
see the defination of the function.

SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;

VOID MyServiceCtrlHandler (DWORD Opcode)
{
DWORD status;

switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.
MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (MyServiceStatusHandle,
&MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
%ld\n",status);
}

SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0);
return;

case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;

default:
SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n",
Opcode);
}

// Send current status.
if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
%ld\n",status);
}
return;
}

muthuis
April 29th, 2003, 04:02 AM
Yup! this is it! This should be enough!

mahanare
April 29th, 2003, 04:53 AM
Originally posted by muthuis
Yup! this is it! This should be enough!

O.K muthu.. did you try the code?
Because I am not admin in my system so I am unable to work on this. getting admin power in HTSL is a process, i have to put a request then IS people have to do the work.
so I didn't try this..
If you can spare some time on this. can you try the code once so that atleast i will be having confidence that the code will work.

thanks in advance.
cheers
mahanare

mahanare
April 30th, 2003, 12:20 PM
AT last now I understood, what was my blunder....
I didn't listen to muthu or mick properly.
so the .exe which is going to be made a service should have some mechinism inside that so that it will respond to the SCM.

well, now i want to work on this.
I got admin privileges again so i will be doing the work myself.
thanks for all the help I got from muthu and Mick.
if i succeed then I will conclude this discussion with some code as a .zip. thanks to one and all for making this thread as one of the hot threads of codeguru.
cheers
mahanare

mahanare
April 30th, 2003, 02:13 PM
Muthu, I did the work in your way. now I agree 200% that normal exe files cann't respond to the SCM calls.
so I changed my exe file ( to be made service ) code and now service Has no problem.
now i can create,start , stop, delete services provided the privilege is held by the user.


Thanks for the help that I got thru this discussion.
When I find some time, I will prepare some good tutorial and update my previous article on codeguru.


cheers
mahanare

muthuis
April 30th, 2003, 08:38 PM
Way to go dude!

ChrisInAvondale
May 1st, 2003, 01:41 PM
Why you are launching an EXE from a service I don't understand, but I'll give you the answer you are looking for. Create a named event in your service by calling CreateEvent(). Then in the EXE call OpenEvent() to get a handle to the same event. When the service needs to shutdown, simply signal the event and have the EXE exit gracefully. This process is easy to implement and allows the EXE to exit properly and clean-up after itself.

Personally, I think you should spend the time to make your EXE into an actual service. This can be done because I've done it before. You don't need to rely on the VC++ wizards to create MFC projects. These wizards aren't doing anything magical. They are just setting the proper project settings, headers, and linking the right libs.

mahanare
May 3rd, 2003, 01:47 AM
Originally posted by ChrisInAvondale
Personally, I think you should spend the time to make your EXE into an actual service. This can be done because I've done it before. You don't need to rely on the VC++ wizards to create MFC projects. These wizards aren't doing anything magical. They are just setting the proper project settings, headers, and linking the right libs.


Hi, Chris
thanks for the reply, Yah I did some work regarding service and my exe with service main is working fine, as a service. I wrote code to do start, stop etc ( even i think i posted the code in this thread only) basically i was just using MSDN ( no books etc at all) so I misunderstood that any .exe can be made into service. But it is not true. the examples i got on net were of single program where they have service main code etc, as well as start stop code also , in the same application so i misunderstood, thinking that CreateService() will convert any .exe to service. but it is not true.

Now as of now I don't have problem in manipulation of services.
Now I want to work on remote service handling.

thanks any way.

cheers
mahanare

mahanare
May 4th, 2003, 11:57 PM
Hi, All.

Thanks to codeguru.com and all the gurus who participated in this discussion thread and helped me enhancing my services knowledge.

As of now I am able to create Service from a console .exe.
Now I want to make a windows based application to a service.
How to go with this?

You can take it like "how to make a dialog based or document-view architecture based application into a service".

Thanks in advance

cheers
mahanare

maron
July 30th, 2003, 01:19 AM
i developed a server program. i need to put it as service so it runs on startup.

how should i go on?
i need to program my application to support service?
but how, i need guidance in this area.
Thanks.

mahanare
July 30th, 2003, 01:22 AM
Originally posted by maron
i developed a server program. i need to put it as service so it runs on startup.

how should i go on?
i need to program my application to support service?
but how, i need guidance in this area.
Thanks.

it depends on what is exactly ur requirement..

if u just need to run it at startup..

you need not do any service work..
just put shortcut in "startup" folder.

service is basically used to run like a "daemon" in linux/unix.

in that case by modifying ur code to support SCM u can make ur application a service.

hope this helps

maron
July 30th, 2003, 01:28 AM
yes, i want it to start it as a NT service.

So what should I start off with.
Provide any samples for me :)

mahanare
July 30th, 2003, 01:32 AM
Originally posted by maron
yes, i want it to start it as a NT service.

So what should I start off with.
Provide any samples for me :)

Yah..
Read this same thread from the beginning and ur will get samples and interesting discussion..

Best of luck.

come back if u have any trouble.

maron
July 30th, 2003, 02:00 AM
what kind of function I need to add in to my program itself.
do I need any standalone program to initialise my exe as a service?

maron
July 30th, 2003, 05:20 AM
so i need to add ServiceMain() in my c++ program itself
and do a separate exe to install/remove the service in the SCM?

maron
July 30th, 2003, 11:28 PM
i run my server as a service but it is using 99-100% of the CPU usage shown in the task manager.

EDIT: solved now. my mistake in a thread.

wiwi
February 11th, 2011, 02:30 AM
Muthu, I did the work in your way. now I agree 200% that normal exe files cann't respond to the SCM calls.
so I changed my exe file ( to be made service ) code and now service Has no problem.
now i can create,start , stop, delete services provided the privilege is held by the user.


Thanks for the help that I got thru this discussion.
When I find some time, I will prepare some good tutorial and update my previous article on codeguru.


cheers
mahanare

Hi,
I am wiwi. I need help to solve the same problem, I also got error 1503, when starting my service.
What do you mean by changed your exe file (to be made) as service?

thanks in advance

Igor Vartanov
February 12th, 2011, 01:42 AM
Writing a Service Program's main Function (http://msdn.microsoft.com/en-us/library/ms687416%28v=vs.85%29.aspx)
Writing a ServiceMain Function (http://msdn.microsoft.com/en-us/library/ms687414%28v=vs.85%29.aspx)

dexblack
February 21st, 2011, 04:59 PM
No need to write a program to start/stop services.
net start service
net stop service

dexblack
February 21st, 2011, 05:14 PM
Or you could just use the service framework library SFL (http://www.rsdn.ru/article/baseserv/sfl.xml)