This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- InstallShield
- :
- InstallShield Forum
- :
- Check if Service Stopped help
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jun 22, 2010
02:03 PM
Check if Service Stopped help
We've built an installer that installs some services which take a long time to stop so we've decided to require the user to shut them down manually. The installer checks to see if the service is running. If it is, it displays a message and aborts the uninstall.
I'm using snippets from ntservice.rul on InstallSite.
The script works to see if the service is available, but chokes on checking to see if it is stopped. It never says it is stopped.
Below is the script we are using.
We call the script from setup. rul:
function CheckService1(hMSI)
STRING szServiceName;
NUMBER bExists;
NUMBER bReturn;
begin
szServiceName = "servicename";
bExists =_IsServiceAvailable(szServiceName);
//MessageBox(bExists, INFORMATION);
if (bExists = 0) then
bReturn = _IsNTServiceStopped(szServiceName);
if (bReturn <0) then
MessageBox(szServiceName + " must be stopped manually", SEVERE);
bReturn =1602;
endif;
endif;
return bReturn;
end;
Our NTService.rul:
#define _NTS_DEBUG
#if _ISCRIPT_VER >= 0x600
#ifndef AddressString
#define AddressString &
#endif
#endif
// constants copied from Winsvc.h
#define SC_MANAGER_ALL_ACCESS 0x000F003F
#define SERVICE_ALL_ACCESS 0x000F01FF
#define SC_MANAGER_CONNECT 0x00000001
// Status
#define SERVICE_STOPPED 0x00000001
#define SERVICE_START_PENDING 0x00000002
#define SERVICE_STOP_PENDING 0x00000003
#define SERVICE_RUNNING 0x00000004
#define SERVICE_CONTINUE_PENDING 0x00000005
#define SERVICE_PAUSE_PENDING 0x00000006
#define SERVICE_PAUSED 0x00000007
typedef SERVICE_STATUS
begin
NUMBER dwServiceType;
NUMBER dwCurrentState;
NUMBER dwControlsAccepted;
NUMBER dwWin32ExitCode;
NUMBER dwServiceSpecificExitCode;
NUMBER dwCheckPoint;
NUMBER dwWaitHint;
end;
// Prototype the service control APIs
prototype NUMBER AdvAPI32.OpenSCManagerA(POINTER, POINTER, NUMBER);
prototype NUMBER AdvAPI32.OpenServiceA(NUMBER, POINTER, NUMBER);
prototype BOOL AdvAPI32.CloseServiceHandle(NUMBER);
prototype BOOL AdvAPI32.QueryServiceStatus(NUMBER, POINTER);
prototype NUMBER KERNEL.GetLastError();
// global service handles, filled and released
POINTER ptrMcName, ptrDBName, pszSStartName;
NUMBER schService, schSCManager;
// prototype the InstallScript functions.
prototype _InitServiceConnections(STRING);
prototype _CloseServiceConnections();
prototype _IsServiceAvailable(STRING);
prototype _IsNTServiceStopped(STRING);
function _InitServiceConnections(szServiceName)
NUMBER nReturn, nResult;
begin
// Initialize global variables
schService = NULL;
schSCManager = NULL;
ptrMcName = NULL; // use local machine
ptrDBName = NULL; // open services active database
// Locals
nReturn = 0;
nResult = 0;
// Load ADVAPI32.DLL, which is necessary for Service Manager-
// related functions.
if (UseDLL("AdvAPI32.dll") < 0) then
#ifdef _NTS_DEBUG
MessageBox ("Couldn't load AdvAPI32.dll.", SEVERE);
#endif
nReturn = -1;
endif;
// First establish the connection with the Service Manager
if (nReturn = 0) then
schSCManager = AdvAPI32.OpenSCManagerA(ptrMcName, ptrDBName, SC_MANAGER_CONNECT);
if (schSCManager = NULL) then
nResult = GetLastError();
#ifdef _NTS_DEBUG
SprintfBox(INFORMATION, "OpenSCManagerA Error",
"Error connecting to Service Manager.\n\n" +
"Error number = %ld.", nResult);
#endif
nReturn = -1;
endif;
endif;
if (szServiceName != "") then
pszSStartName = AddressString(szServiceName); //FIX IS3
if (nReturn = 0) then
// Now open the service.
schService = AdvAPI32.OpenServiceA(schSCManager, pszSStartName, SC_MANAGER_CONNECT); //FIX IS3
if (schService = NULL) then
nResult = GetLastError();
#ifdef _NTS_DEBUG
SprintfBox(INFORMATION, "OpenService Error",
"Error opening service.\n\n"+
"Error number = %ld.", nResult);
#endif
nReturn = -1;
endif;
endif;
endif;
return nReturn;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _CloseServiceConnections()
//
// DESCRIPTION: Closes connections to services and manager
//
// OUTPUT: 0 If function is successful in connecting
// -1 If function fails to connect
/////////////////////////////////////////////////////////////
function _CloseServiceConnections()
NUMBER nResult;
begin
// Close connection to Service Manager
if (schSCManager != NULL) then
nResult = AdvAPI32.CloseServiceHandle(schSCManager);
endif;
// Close handle of the service installed
if (schService != NULL) then
nResult = AdvAPI32.CloseServiceHandle(schService);
endif;
// Deinitialize global variables, just in case
schService = NULL;
schSCManager = NULL;
ptrMcName = NULL; // use local machine
ptrDBName = NULL; // open services active database
UnUseDLL("AdvAPI32.dll");
return nResult;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _IsServiceAvailable(szServiceName)
//
// DESCRIPTION: Checks to see if a service is installed
//
// INPUT: szServiceName = service name to check for
//
// OUTPUT: 0 If service is available
// -1 If service is unavailable
/////////////////////////////////////////////////////////////
function _IsServiceAvailable(szServiceName)
NUMBER nvResult;
begin
nvResult = _InitServiceConnections(szServiceName);
_CloseServiceConnections();
return nvResult;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _IsNTServiceStopped(szSStartName)
//
// DESCRIPTION: Checks to see if a service is stopped
//
// INPUT: szSStartName = String containing the service name on
// the local computer
//
// OUTPUT: 0 If service is stopped
// -1 If service is not stopped
/////////////////////////////////////////////////////////////
function _IsNTServiceStopped(szServiceName)
NUMBER nReturn, nResult;
STRING svString;
STRING sResult;
SERVICE_STATUS ssServiceStatus;
POINTER pssServiceStatus;
begin
// Initialize variables.
nReturn = 0;
nResult = 0;
// Open all our handles
_InitServiceConnections(szServiceName);
pssServiceStatus=AddressString(ssServiceStatus); //FIX IS3
if (nReturn = 0) then
// Check to see if the service is already running
nResult = AdvAPI32.QueryServiceStatus(schService, pssServiceStatus);
if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED) then
nReturn = -1;
endif;
endif;
// close and NULL our handles
_CloseServiceConnections();
return nReturn;
end;
I'm using snippets from ntservice.rul on InstallSite.
The script works to see if the service is available, but chokes on checking to see if it is stopped. It never says it is stopped.
Below is the script we are using.
We call the script from setup. rul:
function CheckService1(hMSI)
STRING szServiceName;
NUMBER bExists;
NUMBER bReturn;
begin
szServiceName = "servicename";
bExists =_IsServiceAvailable(szServiceName);
//MessageBox(bExists, INFORMATION);
if (bExists = 0) then
bReturn = _IsNTServiceStopped(szServiceName);
if (bReturn <0) then
MessageBox(szServiceName + " must be stopped manually", SEVERE);
bReturn =1602;
endif;
endif;
return bReturn;
end;
Our NTService.rul:
#define _NTS_DEBUG
#if _ISCRIPT_VER >= 0x600
#ifndef AddressString
#define AddressString &
#endif
#endif
// constants copied from Winsvc.h
#define SC_MANAGER_ALL_ACCESS 0x000F003F
#define SERVICE_ALL_ACCESS 0x000F01FF
#define SC_MANAGER_CONNECT 0x00000001
// Status
#define SERVICE_STOPPED 0x00000001
#define SERVICE_START_PENDING 0x00000002
#define SERVICE_STOP_PENDING 0x00000003
#define SERVICE_RUNNING 0x00000004
#define SERVICE_CONTINUE_PENDING 0x00000005
#define SERVICE_PAUSE_PENDING 0x00000006
#define SERVICE_PAUSED 0x00000007
typedef SERVICE_STATUS
begin
NUMBER dwServiceType;
NUMBER dwCurrentState;
NUMBER dwControlsAccepted;
NUMBER dwWin32ExitCode;
NUMBER dwServiceSpecificExitCode;
NUMBER dwCheckPoint;
NUMBER dwWaitHint;
end;
// Prototype the service control APIs
prototype NUMBER AdvAPI32.OpenSCManagerA(POINTER, POINTER, NUMBER);
prototype NUMBER AdvAPI32.OpenServiceA(NUMBER, POINTER, NUMBER);
prototype BOOL AdvAPI32.CloseServiceHandle(NUMBER);
prototype BOOL AdvAPI32.QueryServiceStatus(NUMBER, POINTER);
prototype NUMBER KERNEL.GetLastError();
// global service handles, filled and released
POINTER ptrMcName, ptrDBName, pszSStartName;
NUMBER schService, schSCManager;
// prototype the InstallScript functions.
prototype _InitServiceConnections(STRING);
prototype _CloseServiceConnections();
prototype _IsServiceAvailable(STRING);
prototype _IsNTServiceStopped(STRING);
function _InitServiceConnections(szServiceName)
NUMBER nReturn, nResult;
begin
// Initialize global variables
schService = NULL;
schSCManager = NULL;
ptrMcName = NULL; // use local machine
ptrDBName = NULL; // open services active database
// Locals
nReturn = 0;
nResult = 0;
// Load ADVAPI32.DLL, which is necessary for Service Manager-
// related functions.
if (UseDLL("AdvAPI32.dll") < 0) then
#ifdef _NTS_DEBUG
MessageBox ("Couldn't load AdvAPI32.dll.", SEVERE);
#endif
nReturn = -1;
endif;
// First establish the connection with the Service Manager
if (nReturn = 0) then
schSCManager = AdvAPI32.OpenSCManagerA(ptrMcName, ptrDBName, SC_MANAGER_CONNECT);
if (schSCManager = NULL) then
nResult = GetLastError();
#ifdef _NTS_DEBUG
SprintfBox(INFORMATION, "OpenSCManagerA Error",
"Error connecting to Service Manager.\n\n" +
"Error number = %ld.", nResult);
#endif
nReturn = -1;
endif;
endif;
if (szServiceName != "") then
pszSStartName = AddressString(szServiceName); //FIX IS3
if (nReturn = 0) then
// Now open the service.
schService = AdvAPI32.OpenServiceA(schSCManager, pszSStartName, SC_MANAGER_CONNECT); //FIX IS3
if (schService = NULL) then
nResult = GetLastError();
#ifdef _NTS_DEBUG
SprintfBox(INFORMATION, "OpenService Error",
"Error opening service.\n\n"+
"Error number = %ld.", nResult);
#endif
nReturn = -1;
endif;
endif;
endif;
return nReturn;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _CloseServiceConnections()
//
// DESCRIPTION: Closes connections to services and manager
//
// OUTPUT: 0 If function is successful in connecting
// -1 If function fails to connect
/////////////////////////////////////////////////////////////
function _CloseServiceConnections()
NUMBER nResult;
begin
// Close connection to Service Manager
if (schSCManager != NULL) then
nResult = AdvAPI32.CloseServiceHandle(schSCManager);
endif;
// Close handle of the service installed
if (schService != NULL) then
nResult = AdvAPI32.CloseServiceHandle(schService);
endif;
// Deinitialize global variables, just in case
schService = NULL;
schSCManager = NULL;
ptrMcName = NULL; // use local machine
ptrDBName = NULL; // open services active database
UnUseDLL("AdvAPI32.dll");
return nResult;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _IsServiceAvailable(szServiceName)
//
// DESCRIPTION: Checks to see if a service is installed
//
// INPUT: szServiceName = service name to check for
//
// OUTPUT: 0 If service is available
// -1 If service is unavailable
/////////////////////////////////////////////////////////////
function _IsServiceAvailable(szServiceName)
NUMBER nvResult;
begin
nvResult = _InitServiceConnections(szServiceName);
_CloseServiceConnections();
return nvResult;
end;
/////////////////////////////////////////////////////////////
// FUNCTION: _IsNTServiceStopped(szSStartName)
//
// DESCRIPTION: Checks to see if a service is stopped
//
// INPUT: szSStartName = String containing the service name on
// the local computer
//
// OUTPUT: 0 If service is stopped
// -1 If service is not stopped
/////////////////////////////////////////////////////////////
function _IsNTServiceStopped(szServiceName)
NUMBER nReturn, nResult;
STRING svString;
STRING sResult;
SERVICE_STATUS ssServiceStatus;
POINTER pssServiceStatus;
begin
// Initialize variables.
nReturn = 0;
nResult = 0;
// Open all our handles
_InitServiceConnections(szServiceName);
pssServiceStatus=AddressString(ssServiceStatus); //FIX IS3
if (nReturn = 0) then
// Check to see if the service is already running
nResult = AdvAPI32.QueryServiceStatus(schService, pssServiceStatus);
if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED) then
nReturn = -1;
endif;
endif;
// close and NULL our handles
_CloseServiceConnections();
return nReturn;
end;
(3) Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jun 22, 2010
05:52 PM
I haven't tried it, but do built-in functions ServiceExistsService and ServiceGetServiceState work in this situation?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jun 25, 2010
11:07 AM
We have heard that they do not work in all instances, so thought we'd try the script we are using.
Anyone else have any ideas?
Anyone else have any ideas?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jun 25, 2010
11:56 AM
Spdracer,
You are correct... ServiceExistsService does not always work.
This problem was brought to Macrovision's attention in 2007. See
http://community.flexerasoftware.com/showthread.php?t=169135
It is a lengthy post. Toward the end you can see what I did to resolve the problem. This has not been fixed as of IS2010.
You are correct... ServiceExistsService does not always work.
This problem was brought to Macrovision's attention in 2007. See
http://community.flexerasoftware.com/showthread.php?t=169135
It is a lengthy post. Toward the end you can see what I did to resolve the problem. This has not been fixed as of IS2010.