Solved by writing my own installer.
All I do is embed the output of the service project as resources into the installer project, and write them to a specified folder.
Then I run installutil programmatically, which installs the service just fine, and then it works.
The only drawback compared to a real installer is, this way there is no uninstaller, but I don't care anymore. When it's days faster to roll your own installer than using InstallShield, then there is something wrong with InstallShield.
Reinventing the wheel may lead to errors, but at least they are mine to make and solvable.
Here the solution, in case it is useful to anybody else.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace SimpleInstaller
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static int Main(string[] args)
{
if (false)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
//for (int i = 0; i < args.Length; ++i)
//{
// Console.WriteLine("args[{0}] = {1}", i, args[i]);
//}
string strPath = @"C:\pro\DbBackupService\DbBackupService\bin\Debug\DbBackupService.exe";
string[] callArgs = null;
string[] argInstall = new string[] { strPath };
string[] argUnInstall = new string[] { "/u", strPath };
bool bIsInstallation = true;
bIsInstallation = false;
callArgs = bIsInstallation ? argInstall : argUnInstall;
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CurrentUICulture.GetConsoleFallbackUICulture();
//if(Console.OutputEncoding.CodePage != 65001 && Console.OutputEncoding.CodePage !=
if (Console.OutputEncoding.CodePage != 65001
&& Console.OutputEncoding.CodePage != System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.OEMCodePage
&& Console.OutputEncoding.CodePage != System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.ANSICodePage)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
}
try
{
System.Configuration.Install.ManagedInstallerClass.InstallHelper(callArgs);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
//return -1;
}
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
return 0;
} // End Sub Main
} // End Class Program
} // End Namespace SimpleInstaller