Windows 服务的 Inno 安装程序? ?

我有一个.NetWindows 服务。我想创建一个安装程序来安装该 Windows 服务。

基本上,它必须做到以下几点:

  1. 包装 installutil.exe(是否需要?)
  2. 运行 installutil.exe MyService.exe
  3. 启动我的服务

另外,我想提供一个卸载程序,它运行以下命令:

installutil.exe /u MyService.exe

如何使用 Inno 安装程序进行这些操作?

57375 次浏览

You don't need installutil.exe and probably you don't even have rights to redistribute it.

Here is the way I'm doing it in my application:

using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;


static void Main(string[] args)
{
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "--install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
break;
case "--uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
}
}
else
{
ServiceBase.Run(new WindowsService());
}
}

Basically you can have your service to install/uninstall on its own by using ManagedInstallerClass as shown in my example.

Then it's just matter of adding into your InnoSetup script something like this:

[Run]
Filename: "{app}\MYSERVICE.EXE"; Parameters: "--install"


[UninstallRun]
Filename: "{app}\MYSERVICE.EXE"; Parameters: "--uninstall"

If you want to avoid reboots when the user upgrades then you need to stop the service before copying the exe and start again after.

There are some script functions to do this at Service - Functions to Start, Stop, Install, Remove a Service

You can use

Exec(
ExpandConstant('{sys}\sc.exe'),
ExpandConstant('create "MyService" binPath= {app}\MyService.exe start= auto DisplayName= "My Service" obj= LocalSystem'),
'',
SW_HIDE,
ewWaitUntilTerminated,
ResultCode
)

to create a service. See "sc.exe" on how to start, stop, check service status, delete service, etc.

Here's how i did it:

Exec(ExpandConstant('{dotnet40}\InstallUtil.exe'), ServiceLocation, '', SW_HIDE, ewWaitUntilTerminated, ResultCode);

Apparently, Inno setup has the following constants for referencing the .NET folder on your system:

  • {dotnet11}
  • {dotnet20}
  • {dotnet2032}
  • {dotnet2064}
  • {dotnet40}
  • {dotnet4032}
  • {dotnet4064}

More information available here.

have a look at topshelf http://topshelf-project.com/

  • it lets you develop your service as a console application

  • adds a start/stop service as an API to your service...

  • ... that you can call from InnoSetup

    [Run] Filename: "{app}\myservice.exe"; Parameters: "stop" ; Flags : waituntilterminated Filename: "{app}\myservice.exe"; Parameters: "uninstall" ; Flags : waituntilterminated Filename: "{app}\myservice.exe"; Parameters: "install -description ""myservice""" ; Flags : waituntilterminated