【问题标题】:Inno Setup for Windows service?Windows 服务的 Inno 设置?
【发布时间】:2010-11-29 19:36:17
【问题描述】:

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

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

  1. 打包installutil.exe(需要吗?)
  2. 运行installutil.exeMyService.exe
  3. 启动我的服务

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

installutil.exe /u MyService.exe

如何使用 Inno Setup 进行这些操作?

【问题讨论】:

  • 我认为您需要使用 [Run] 部分。见here

标签: c# windows-services inno-setup


【解决方案1】:

您不需要installutil.exe,而且您可能甚至没有重新分发它的权利。

这是我在应用程序中的做法:

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());
    }
}

基本上,您可以使用ManagedInstallerClass 让您的服务自行安装/卸载,如我的示例所示。

然后只需在您的 InnoSetup 脚本中添加如下内容:

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

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

【讨论】:

  • 你可以试试Filename: "net.exe"; Parameters: "start WinServ"。如果它不起作用,您可以在您的 c# 应用程序中再添加一个开关 --start 并使用 ServiceController 类 (msdn.microsoft.com/en-us/library/…) 直接从程序启动 windows 服务。
  • 对于 C# 新手(如我),您需要在上面的代码中添加 using System.Reflection; 或将 Assembly 更改为 System.Reflection.Assembly
  • InstallUtil 是 dot net 框架的一部分,你不需要“权限”来重新分发它,它已经存在于你的目标系统上(当然假设你可以首先运行你的应用程序)
  • 来自关于 4.5 中 InstallHelper 方法的文档 - “此 API 支持 .NET Framework 基础结构,不打算直接从您的代码中使用。”收到 System.InvalidOperationException 后发现。
【解决方案2】:

我是这样做的:

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

显然,Inno setup 有以下常量用于引用系统上的 .NET 文件夹:

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

更多信息here

【讨论】:

    【解决方案3】:

    你可以使用

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

    创建服务。有关如何启动、停止、检查服务状态、删除服务等,请参阅“sc.exe”。

    【讨论】:

      【解决方案4】:

      如果您想避免在用户升级时重新启动,那么您需要在复制 exe 之前停止服务并在之后重新启动。

      Service - Functions to Start, Stop, Install, Remove a Service 有一些脚本函数可以执行此操作

      【讨论】:

      • 在您的链接文章中,所用函数的原型没有精确翻译,它们的使用也不正确(例如,没有等待服务启动、停止等)。
      【解决方案5】:

      看看topshelf http://topshelf-project.com/

      • 它允许您将服务开发为控制台应用程序

      • 将启动/停止服务作为 API 添加到您的服务...

      • ...你可以从 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多