Stopping a Windows service C program example using Win32 library
// For WinXp as a target
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
DWORD StopService(SC_HANDLE, SC_HANDLE, BOOL, DWORD);
void DisplayError(LPTSTR, DWORD);
// Entry point for the program. This function contains sample code demonstrating how to use the StopService function implemented above.
//
// Parameters:
// argc - the number of command-line arguments
// argv[] - an array of command-line arguments
// Using _tmain(), TCHAR - A WCHAR if UNICODE is defined, a CHAR otherwise.
void _tmain(int argc, TCHAR *argv[])
{
SC_HANDLE hSCM;
SC_HANDLE hService;
DWORD dwError;
// If no command line argument supplied...
if (argc <2> dwTimeout)
return ERROR_TIMEOUT;
}
// If the service is running, dependencies must be stopped first
if (fStopDependencies)
{
DWORD i;
DWORD dwBytesNeeded;
DWORD dwCount;
LPENUM_SERVICE_STATUS lpDependencies = NULL;
ENUM_SERVICE_STATUS ess;
SC_HANDLE hDepService;
// Pass a zero-length buffer to get the required buffer size
if ((EnumDependentServices(hService, SERVICE_ACTIVE,
lpDependencies, 0, &dwBytesNeeded, &dwCount)) != 0)
{
_tprintf(TEXT("EnumDependentServices(), no dependencies lol!\n"));
// If the Enum call succeeds, then there are no dependent services so do nothing...
}
else
{
_tprintf(TEXT("EnumDependentServices(), there are dependencies lol!\n"));
if (GetLastError() != ERROR_MORE_DATA)
return GetLastError(); // Unexpected error
// Allocate a buffer for the dependencies
lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded);
if (!lpDependencies)
return GetLastError();
__try {
// Enumerate the dependencies
if (!EnumDependentServices(hService, SERVICE_ACTIVE,
lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount))
return GetLastError();
_tprintf(TEXT("The number of dependencies: %d.\n"), dwCount);
for (i = 0; i <dwCount> dwTimeout)
return ERROR_TIMEOUT;
}
}
__finally
{
// Always release the service handle
if (CloseServiceHandle(hDepService) == 0)
_tprintf(TEXT("CloseServiceHandle() failed, error: %d.\n"), GetLastError());
else
_tprintf(TEXT("CloseServiceHandle() looks OK.\n"));
}
}
}
__finally
{
// Always free the enumeration buffer
if (HeapFree(GetProcessHeap(), 0, lpDependencies) == 0)
_tprintf(TEXT("HeapFree() failed, error: %d.\n"), GetLastError());
else
_tprintf(TEXT("HeapFree() looks OK.\n"));
}
}
}
// Assuming all dependencies already stopped, send a stop code to the main service
if (!ControlService(hService, SERVICE_CONTROL_STOP, &ss))
return GetLastError();
// Wait for the service to stop
while (ss.dwCurrentState != SERVICE_STOPPED)
{
Sleep(10000);
//Sleep(ss.dwWaitHint);
if (!QueryServiceStatus(hService, &ss))
return GetLastError();
if (ss.dwCurrentState == SERVICE_STOPPED)
// The main service was stopped...
break;
if (GetTickCount() - dwStartTime > dwTimeout)
return ERROR_TIMEOUT;
}
// Return success
return ERROR_SUCCESS;
}
// Helper function to display an error message
void DisplayError(LPTSTR szAPI, DWORD dwError)
{
LPTSTR lpBuffer = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpBuffer, 0, NULL);
_tprintf(TEXT("%s failed:\n"), szAPI);
_tprintf(TEXT(" error code = %u\n"), dwError);
_tprintf(TEXT(" message = %s\n"), lpBuffer);
if (LocalFree(lpBuffer) == NULL)
_tprintf(TEXT("LocalFree() looks OK.\n"));
else
_tprintf(TEXT("LocalFree() failed.\n"));
}
Output examples:
(This program run at the command prompt)
F:\vc2005project\cplus\debug>cplus
usage: cplus <ServiceName>
Example: cplus Telnet
Please try again.
F:\vc2005project\cplus\debug>cplus Alerter
OpenSCManager() looks OK.
OpenService() looks OK.
QueryServiceStatus(), querying the service status...
Service already stopped.
The Alerter service was successfully stopped.
F:\vc2005project\cplus\debug>cplus Browser
OpenSCManager() looks OK.
OpenService() looks OK.
QueryServiceStatus(), querying the service status...
Checking the service pending status...
EnumDependentServices(), no dependencies lol!
The Browser service was successfully stopped.
F:\vc2005project\cplus\debug>cplus Dnscache
OpenSCManager() looks OK.
OpenService() looks OK.
QueryServiceStatus(), querying the service status...
Checking the service pending status...
EnumDependentServices(), no dependencies lol!
The Dnscache service was successfully stopped.
F:\vc2005project\cplus\debug>
If the service is set to manual start:
F:\vc2005project\cplus\debug>cplus TIntSvr
OpenSCManager() looks OK.
OpenService() failed.
failed:
error code = 1060
message = The specified service does not exist as an installed service.
LocalFree() looks OK.
Verify that the service has been stopped.
Compiler: Visual C++ Express Edition 2005
Compiled on Platform: Windows XP Pro SP2
Target platform: none, just for learning and fun
Header file: Standard and Windows
Additional library: Windows Platform SDK
Additional project setting: Set project to be compiled as C. Click Project menu->your_project_name Properties->Configuration Properties->C/C++->Advanced->Compiled As: Compiled as C Code (/TC)
Other info: non-CLR or unmanaged. Need to add Advapi32.lib (Advapi32.dll) to the project. Click the Project menu->Select the your_project_name Properties... sub menu->Expand the Configuration Properties folder on the left pane->Expand the Linker subfolder->Select the Input subfolder->Select the Additional Dependencies field on the right pane->Click the ... at the end of the field->Type in 'Advapi32.lib' in the empty pane->Click the OK button->Click the OK button second time to close the project Properties dialog.
To do: Stopping a Windows service programmatically using C source code sample from Win32 library
To show: The Windows service and related functions available in Win32 library