C# Windows服务的Inno安装程序?

C# Windows服务的Inno安装程序?,c#,windows-services,inno-setup,C#,Windows Services,Inno Setup,我有一个.Net Windows服务。我想创建一个安装程序来安装该windows服务 基本上,它必须做到以下几点: Packinstallutil.exe(它是必需的吗?) 运行installutil.exeMyService.exe 启动我的服务 此外,我还想提供一个运行以下命令的卸载程序: installutil.exe /u MyService.exe 如何使用Inno安装程序执行这些操作?您不需要installutil.exe,甚至可能没有重新分发它的权限 以下是我在应用程序中的操作方

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

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

  • Pack
    installutil.exe
    (它是必需的吗?)
  • 运行
    installutil.exe
    MyService.exe
  • 启动我的服务
  • 此外,我还想提供一个运行以下命令的卸载程序:

    installutil.exe /u MyService.exe
    

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

    您不需要
    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());
        }
    }
    
    基本上,您可以使用自己的服务来安装/卸载,如我的示例所示

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

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

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

    中可以使用一些脚本函数来执行此操作

    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

    以下是我的操作方法:

    Exec(ExpandConstant('{dotnet40}\InstallUtil.exe'), ServiceLocation, '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
    
    显然,Inno安装程序具有以下常量,用于引用系统上的.NET文件夹:

    • {dotnet11}
    • {dotnet20}
    • {dotnet2032}
    • {dotnet2064}
    • {dotnet40}
    • {dotnet4032}
    • {dotnet4064}
    更多信息可用。

    查看topshelf

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

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

    • 。。。您可以从InnoSetup调用

      [Run]文件名:“{app}\myservice.exe”;参数:“停止”;标志:WaitUnterminated文件名:“{app}\myservice.exe”;参数:“卸载”;标志:WaitUnterminated文件名:“{app}\myservice.exe”;参数:“安装-说明”“myservice”“”;标志:WaitUntFilterminated


    您可以尝试
    文件名:“net.exe”;参数:“启动WinServ”
    。如果它不起作用,您可以再添加一个开关——启动c#应用程序,并使用ServiceController类()直接从程序启动windows服务。对于C#新手(像我一样),您需要使用System.Reflection添加
    或将
    Assembly
    更改为
    System.Reflection.Assembly
    在上面的代码中。InstallUtil是dot net framework的一部分,您不需要“权限”来重新分发它,它已经存在于您的目标系统中(当然,假设您首先可以运行应用程序)从4.5中有关InstallHelper方法的文档中可以看出-“此API支持.NET Framework基础结构,不打算直接从代码中使用。”在收到System.InvalidOperationException.后发现。在您的链接文章中,所用函数的原型没有准确翻译,其用法也不正确(例如,没有等待服务启动、停止等)。我认为您需要使用[运行]部分。看见