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
- :
- ServiceAddService returns -1
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
‎Jul 09, 2008
10:29 AM
ServiceAddService returns -1
Hello,
ServiceAddService return -1. This is no >= ISERR_SUCCESS. And Format function gives no text message for this code. What does this code mean?
ServiceAddService return -1. This is no >= ISERR_SUCCESS. And Format function gives no text message for this code. What does this code mean?
14 Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 09, 2008
12:45 PM
Can you tell us what project type it is and a code snippet? If MSI, how are you scheduling it?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 09, 2008
02:31 PM
Yes, this is a Basic MSI type.
As far as I remember (I am now at home and will check it tomorrow and send a snippet) it is scheduled after InstallServices action.
And in fact it is installed despite -1 error code and successfully started.
As far as I remember (I am now at home and will check it tomorrow and send a snippet) it is scheduled after InstallServices action.
And in fact it is installed despite -1 error code and successfully started.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 10, 2008
02:09 AM
Here is the whole function that installs Windows Service with relevant comments:
//
// Installs QEF as Windows service.
// This CA is deferred and used after InstallServices and SetInstallWindowsServiceData actions.
//
function InstallWindowsService(hMSI)
LIST lCustomActionData; // CA data list
STRING svServiceName, // QEF Windows service name
svDisplayName, // QEF Windows service display name
svDescription; // QEF Windows service description
STRING svCustomActionData, // CA data string
svBinDir, // Bin directory
svAccountType, // QEF Windows service account type
svLogin, // QEF Windws service login
svPassword, // QEF Windws service password
svStartupType, // QEF Windws service startup type
svStartAfterInstall; // QEF Windws service start after insttallation value
STRING svScriptFile, // script file in which the error occurred
svError, // error code for the error
svErrorMessage; // error message
NUMBER nvSize, // size of buffer used to get MSI properties
nResult, // result code
nAccountType, // QEF Windows service account type
nStartupType; // QEF Windws service startup type
NUMBER nvLineNumber, // line number in which the error occurred
nvError; // error code for the error
BOOL bStartAfterInstall; // QEF Windws service start after insttallation value
begin
svServiceName = "QEF";
svDisplayName = "QualiWare Execution Framework";
svDescription = "Enables deployment of QualiWare modules, management of user and groups, security and licensing, logging and monitoring.";
// Check if QEF Windows service is already installed.
if(ServiceExistsService(svServiceName) = TRUE) then
MessageBox("Cannot install Windows Servcie, because Windows Service with name \"" + svServiceName + "\" already exists!", WARNING);
return NOTHING;
endif;
nvSize = 256;
nvError = -1;
// Get CA data as a string.
nResult = MsiGetProperty(hMSI, "CustomActionData", svCustomActionData, nvSize);
if(nResult != ERROR_SUCCESS) then
MessageBox("Cannot get CA data!", SEVERE);
endif;
// Convert CA data from string to list.
lCustomActionData = ListCreate(STRINGLIST);
if (StrGetTokens(lCustomActionData, svCustomActionData, ";") > 0) then
MessageBox ("Failed to get tokens from string!", SEVERE);
endif;
// Get Bin directory from CA data list.
nResult = ListGetFirstString(lCustomActionData, svBinDir);
if(nResult = -1) then
MessageBox("Cannot get Bin directory path!", SEVERE);
endif;
// Get QEF Windows service accoount type from CA data list.
nResult = ListGetNextString(lCustomActionData, svAccountType);
if(nResult = -1) then
MessageBox("Cannot get Windows service account type!", SEVERE);
endif;
// Get QEF Windows service login from CA data list.
nResult = ListGetNextString(lCustomActionData, svLogin);
if(nResult = -1) then
MessageBox("Cannot get Windows service login!", SEVERE);
endif;
// Get QEF Windows service password from CA data list.
nResult = ListGetNextString(lCustomActionData, svPassword);
if(nResult = -1) then
MessageBox("Cannot get Windows service password!", SEVERE);
endif;
// Get QEF Windows service startup type from CA data list.
nResult = ListGetNextString(lCustomActionData, svStartupType);
if(nResult = -1) then
MessageBox("Cannot get Windows service startup type!", SEVERE);
endif;
// Get QEF Windws service start after insttallation value from CA data list.
nResult = ListGetNextString(lCustomActionData, svStartAfterInstall);
if(nResult = -1) then
MessageBox("Cannot get Windows service start after install value!", SEVERE);
endif;
// Destroy CA data list.
ListDestroy (lCustomActionData);
// Convert QEF Windows service account type from string to integer.
StrToNum(nAccountType, svAccountType);
// Set QEF Windows service login and password if account type is set to user account.
if(nAccountType = 1) then
SERVICE_IS_PARAMS.lpServiceStartName = &svLogin;
SERVICE_IS_PARAMS.lpPassword = &svPassword;
endif;
// Convert QEF Windows service startup type from string to integer.
StrToNum(nStartupType, svStartupType);
// Set QEF Windows service startup type.
switch(nStartupType)
case 0:
SERVICE_IS_PARAMS.dwStartType = SERVICE_AUTO_START;
case 1:
SERVICE_IS_PARAMS.dwStartType = SERVICE_DEMAND_START;
case 2:
SERVICE_IS_PARAMS.dwStartType = SERVICE_DISABLED;
endswitch;
// Convert QEF Windows service start after insttallation value from string to integer.
StrToNum(bStartAfterInstall, svStartAfterInstall);
nvError = ServiceAddService(svServiceName, svDisplayName, svDescription, svBinDir ^ "Qef.exe /RunAsService", bStartAfterInstall, "");
NumToStr(svError, nvError);
MessageBox("Exit code: " + svError, INFORMATION);
NumToStr(svError, ISERR_SUCCESS);
MessageBox("ISERR_SUCCESS code: " + svError, INFORMATION);
// Add QEF Windows service to the list of services to install.
if(nvError < ISERR_SUCCESS) then
svErrorMessage = "Windows sevice \"" + svServiceName + "\" cannot be installed!";
GetExtendedErrInfo(svScriptFile, nvLineNumber, nvError);
NumToStr(svError, nvError);
if(nvError = 1057) then // 1069 - wrong password
svErrorMessage = svErrorMessage + " The account name is invalid or does not exist!";
elseif(nvError = 1069) then
svErrorMessage = svErrorMessage + " The service did not start due to a logon failure!";
elseif(nvError = 2) then
svErrorMessage = "";
else
svErrorMessage = svErrorMessage + " Error code: " + svError;
endif;
MessageBox(svErrorMessage, WARNING);
endif;
end;
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 10, 2008
11:29 AM
If your using Basic MSI, what problem are you trying to solve that requires you to roll all of this code instead of just using the ServiceInstall table?

Not applicable
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 10, 2008
12:55 PM
This probably means that the service did not start in the time alloted by the function. Try calling GetExtendedErrInfo, this may give you more error information.
Devin Ellingson
Software Developer
Acresso Software
Devin Ellingson
Software Developer
Acresso Software

Not applicable
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 10, 2008
01:11 PM
ServiceAddService returns a generic success/failure message and the error message can be gathered by calling GetLastError().
More info can be found here:
http://helpnet.acresso.com/robo/projects/installshield15langref/serviceaddservice.htm
More info can be found here:
http://helpnet.acresso.com/robo/projects/installshield15langref/serviceaddservice.htm
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 11, 2008
10:06 AM
The reason for using this script is to give user notifications and it is not flexible enough to run it either under System account or user account depending on user settings during installation.
GetExtendedErrInfo gives empty string.
GetLastError is a Windows API function invoked by GetExtendedErrInfo.
GetExtendedErrInfo gives empty string.
GetLastError is a Windows API function invoked by GetExtendedErrInfo.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 11, 2008
10:48 AM
If you mean to say that you give the user a choice as to what account to use to install the service, the ServiceInstall table's StartName and Password columns are formattable. You could create a dialog that collects the information into properties and then use that to create the service.
There are a couple ugly spots in MSI when it comes to authenticating the provided credentials and assining the LogonAsService right however.
There are a couple ugly spots in MSI when it comes to authenticating the provided credentials and assining the LogonAsService right however.

Not applicable
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 12, 2008
09:46 PM
Correct.
So you're saying that the GetExtErrorInfo's 3rd parameter is returning 0?
Based on how those APIs are invoked, I can't imagine a situation in which that's really possible, but if that's what you're seeing then it sounds like maybe an exception is being thrown.
So you're saying that the GetExtErrorInfo's 3rd parameter is returning 0?
Based on how those APIs are invoked, I can't imagine a situation in which that's really possible, but if that's what you're seeing then it sounds like maybe an exception is being thrown.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 13, 2008
08:27 AM
I actually use a custom dialog to collect information from user. And then install the service with specified parameters with the help of ServiceAddService function. I have not come across any other documented way to do this (except using Services view that is I cannot use).
ServiceAddService function returns -1. And if I use GetExtendedErrInfo I get the same error number: -1. And when I try to use format function I get empty string.
ServiceAddService function returns -1. And if I use GetExtendedErrInfo I get the same error number: -1. And when I try to use format function I get empty string.

Not applicable
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 15, 2008
12:40 AM
-1 is ISERR_GEN_FAILURE, FormatMessage only handles some errors, so you probably won't get any text for this error.
Do the svScriptFile and nvLineNumber parameters return anything?
Devin Ellingson
Software Developer
Acresso Software
Do the svScriptFile and nvLineNumber parameters return anything?
Devin Ellingson
Software Developer
Acresso Software
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 15, 2008
03:21 AM
Here is what script file and line number values are set to:
---------------------------
*** - InstallShield Wizard
---------------------------
Script file: C:\CodeBases\isdev\Script\ISRT\Src\Service.rul
Line number: 561
---------------------------
OK
---------------------------
---------------------------
*** - InstallShield Wizard
---------------------------
Script file: C:\CodeBases\isdev\Script\ISRT\Src\Service.rul
Line number: 561
---------------------------
OK
---------------------------

Not applicable
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 16, 2008
03:27 AM
This indicates that the we did not detect that the service started in the time alloted (which is INFINITE by default).
Check the values in the public 'SERVICE_IS_STATUS' structure instance, we populate this structure with the final values that we got (check dwCurrentState especially).
One possibility is that the service is failing to report SERVICE_START_PENDING during the startup time, in this case the service code will fail in this way.
Devin Ellingson
Software Developer
Acresso Software
Check the values in the public 'SERVICE_IS_STATUS' structure instance, we populate this structure with the final values that we got (check dwCurrentState especially).
One possibility is that the service is failing to report SERVICE_START_PENDING during the startup time, in this case the service code will fail in this way.
Devin Ellingson
Software Developer
Acresso Software
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 04, 2018
01:00 AM
DevinEllingson wrote:
This indicates that the we did not detect that the service started in the time alloted (which is INFINITE by default).
Check the values in the public 'SERVICE_IS_STATUS' structure instance, we populate this structure with the final values that we got (check dwCurrentState especially).
One possibility is that the service is failing to report SERVICE_START_PENDING during the startup time, in this case the service code will fail in this way.
Devin Ellingson
Software Developer
Acresso Software
My case is this one, the service is in service_start_pending state.
