Code:
#pragma comment( lib, "advapi32.lib" )
#include <stdio.h>
#include <windows.h>
#include <winsvc.h>
#include <lmerr.h>
VOID DisplayErrorText(DWORD dwLastError )
{
HMODULE hModule = NULL; // default to system source
LPSTR MessageBuffer;
DWORD dwBufferLength;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM ;
if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
hModule = LoadLibraryEx(
TEXT("netmsg.dll"),
NULL,
LOAD_LIBRARY_AS_DATAFILE
);
if(hModule != NULL)
dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}
if(dwBufferLength = FormatMessageA(
dwFormatFlags,
hModule, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten;
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
LocalFree(MessageBuffer);
}
if(hModule != NULL)
FreeLibrary(hModule);
}
BOOL LaterOSVersion(void)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
// If that fails, try using the OSVERSIONINFO structure.
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return FALSE;
}
if ( osvi.dwMajorVersion <= 4 )
return FALSE;
else
return TRUE;
}
VOID Install(char* pPath, char* pName, char *pComputerName)
{
SERVICE_DESCRIPTION sdBuf;
SC_HANDLE schService;
SC_HANDLE schSCManager = OpenSCManager( pComputerName, NULL, SC_MANAGER_CREATE_SERVICE);
if (schSCManager==0)
{
DWORD dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
schService = CreateService
(
schSCManager, /* SCManager database */
pName, /* name of service */
pName, /* service name to display */
SERVICE_ALL_ACCESS, /* desired access */
SERVICE_WIN32_OWN_PROCESS, /* service type */
SERVICE_AUTO_START, /* start type */
SERVICE_ERROR_NORMAL, /* error control type */
pPath, /* service's binary */
NULL, /* no load ordering group */
NULL, /* no tag identifier */
NULL, /* no dependencies */
NULL, /* LocalSystem account */
NULL /* no password */
);
if (schService==0)
{
DWORD dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
printf("Service %s installed\n", pName);
sdBuf.lpDescription = "MyService It does what it's supposed to";
if( LaterOSVersion() == TRUE)
{
if( !ChangeServiceConfig2
(
schService, // handle to service
SERVICE_CONFIG_DESCRIPTION, // change: description
&sdBuf) ) // value: new description
{
DWORD dwError = GetLastError();
DisplayErrorText(dwError );
}
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
}
VOID UnInstall(char* pName,char *pComputerName)
{
DWORD dwError;
SC_HANDLE schSCManager = OpenSCManager( pComputerName, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == 0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService==0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
if(!DeleteService(schService))
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
printf("Service %s removed\n",pName);
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
}
BOOL KillService(char* pName, char *pComputerName)
{
DWORD dwError, dwTimeout= 0;
SERVICE_STATUS ss;
DWORD dwStartTime = GetTickCount();
DWORD dwBytesNeeded;
SC_HANDLE schSCManager = OpenSCManager( pComputerName, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService==0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
// Make sure the service is not already stopped
QueryServiceStatusEx(
schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ss,
sizeof(SC_STATUS_PROCESS_INFO),
&dwBytesNeeded );
if ( ss.dwCurrentState == SERVICE_STOPPED )
return TRUE;
// If a stop is pending, just wait for it
while ( ss.dwCurrentState == SERVICE_STOP_PENDING )
{
Sleep( ss.dwWaitHint );
if ( !QueryServiceStatusEx(
schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ss,
sizeof(SC_STATUS_PROCESS_INFO),
&dwBytesNeeded ) )
return FALSE;
if ( ss.dwCurrentState == SERVICE_STOPPED )
return TRUE;
if ( GetTickCount() - dwStartTime > dwTimeout )
return FALSE;
}
// call ControlService to kill the given service
SERVICE_STATUS status;
if(ControlService(schService,SERVICE_CONTROL_STOP,&status))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
printf("%s killed\n",pName);
return TRUE;
}
else
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
}
BOOL RunService(char* pName, int nArg, char** pArg, char *pComputerName)
{
DWORD dwError = 0l;
SC_HANDLE schSCManager = OpenSCManager( pComputerName, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService==0)
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
else
{
// call StartService to run the service
if(StartService(schService,nArg,(const char**)pArg))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
printf("%s has succesfully started", pName);
return TRUE;
}
else
{
dwError = GetLastError();
DisplayErrorText(dwError );
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
}
INT main(VOID)
{
char ServiceName[] = {"MyService"};
char ServiceExecutable[] = {"C:\\Temp\\MyService.exe"};
Install(ServiceExecutable, ServiceName, NULL);
RunService(ServiceName,0,NULL, NULL);
// KillService(ServiceName, NULL);
// UnInstall(ServiceName, NULL);
return 0;
}