how can I send command to a Windows service from C++? Equivalent .NET code is:
ServiceController sc = new ServiceController("MyService");
sc.ExecuteCommand(255);
how can I send command to a Windows service from C++? Equivalent .NET code is:
ServiceController sc = new ServiceController("MyService");
sc.ExecuteCommand(255);
Here is a little program which will connect to a service called "MYSERVICE" then send a command 141 (which is defined by the service)
// ServiceCommunicator.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
SC_HANDLE managerHandle;
SC_HANDLE serviceHandle;
SERVICE_STATUS controlParms;
DWORD retStatus;
managerHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
if (NULL != managerHandle)
{
serviceHandle = OpenService(managerHandle, L"MYSERVICE", SERVICE_USER_DEFINED_CONTROL | SERVICE_QUERY_STATUS);
if (NULL != serviceHandle)
{
cout << "connected to Service" << endl;
retStatus = ControlService(serviceHandle, 141, &controlParms);
if (retStatus)
{
//Get the return code from the service
cout << "For command 141, return code from service was " << controlParms.dwWin32ExitCode << endl;
}
else
cout << "Sending command 141 failed" << endl;
CloseServiceHandle(serviceHandle);
}
else
{
cout << "could not connect to Service" << endl;
}
CloseServiceHandle(managerHandle);
}
else
{
cout << "could not open service manager" << endl;
}
return 0;
}
From native C++, you will need to:
For example, this code restarts the time synchronization service. First, I create a wrapper class for the service handles, to close them automatically when leaving the block.
Then, I open the service control manager (using OpenSCManager()) and the service I want to control. Note that the dwDesiredAccess parameter to OpenService() must include permissions for each control I want to send, or the relevant control functions will fail.
To stop the service, I use ControlService() to send the SERVICE_CONTROL_STOP code, and then check the return value to make sure the command succeeded. If any error other than ERROR_SERVICE_NOT_ACTIVE is reported, I assume that starting the service is not going to succeed.
After instructing the service to stop, I wait for the service manager to report that the service is in fact stopped. This code has two potential bugs, which you may wish to correct for production code:
The DWORD returned from GetTickCount() will wrap around to zero eventually; if it wraps around while this function is waiting, the wait may give up sooner than I intended.
Finally, knowing that the service is in a stopped state, I call StartService() run it again.