Google Search

Google Search Results

Tuesday, September 9, 2008

Windows NT Services, Install and Uninstall

Here is some generic code that I use in all of my applications that run as a service. Just call InstallService() to install, and UninstallService() to uninstall. This code doesn't really need VCL or any other libraries (just replace the one part that uses AnsiString with sprintf() or whatever you want), it is really just Win32 API calls, so should be easy to take this code and use in Pascal, VB, or whatever you want.

This is just a function I use instead of MessageBox, in the code below. AppDisplayName is whatever your application is named, I use "const char*" for this variable.

static void ShowPrompt(char *text)
{
MessageBox(NULL,text,AppDisplayName,0);
}

static void InstallService(void)
{
// Load SCM.
SC_HANDLE scm = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if(!scm)
{
ShowPrompt("Error opening SCM, unable to install service.");
return;
}

char filename[MAXPATH];
GetModuleFileName(GetModuleHandle(NULL),filename,sizeof(filename));

// Create our service and give it the path to our EXE.
// We create an auto-load service which will load at system startup.
SC_HANDLE sh = CreateService(scm,AppDisplayName,AppDisplayName,
SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,
filename,NULL,NULL,NULL,NULL,NULL);
if(!sh)
{
ShowPrompt("Error installing service.");
CloseServiceHandle(scm);
return;
}

// Start our service.
if(!StartService(sh,0,NULL))
{
ShowPrompt("Error starting service.");
CloseServiceHandle(sh);
CloseServiceHandle(scm);
return;
}

// Close handles.
CloseServiceHandle(sh);
CloseServiceHandle(scm);

AnsiString aStr;
aStr.sprintf("%s has been installed and is now running as a service.",AppDisplayName);
ShowPrompt(aStr.c_str());
}

static void UninstallService(void)
{
// Load SCM.
SC_HANDLE scm = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if(!scm)
{
ShowPrompt("Error opening SCM, unable to uninstall service.");
return;
}

SC_HANDLE sh = OpenService(scm,AppDisplayName,SERVICE_ALL_ACCESS);
if(!sh)
{
CloseServiceHandle(scm);
ShowPrompt("Unable to open service, it may not be installed.");
return;
}

// Tell service to stop, but we don't care if this fails (it usually
// just means the service isn't running, but not matter what we want
// to try to uninstall anyway).
SERVICE_STATUS ss;
ControlService(sh,SERVICE_CONTROL_STOP,&ss);

// Uninstall service.
if(!DeleteService(sh))
{
if(GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE)
{
CloseServiceHandle(sh);
CloseServiceHandle(scm);
ShowPrompt("Unable to uninstall service.");
return;
}
}

// Close handles.
CloseServiceHandle(sh);
CloseServiceHandle(scm);

ShowPrompt("Service uninstalled.");
}

No comments: