• Inno Setup for Windows service


    I have a .Net Windows service. I want to create an installer to install that windows service.

    Basically, it has to do the following:

    1. Pack installutil.exe (Is it required?)
    2. Run installutil.exe MyService.exe
    3. Start MyService

    Also, I want to provide an uninstaller which runs the following command:

    installutil.exe /u MyService.exe

    How to do these using Inno Setup?

    shareimprove this question
     
        
    I think you need to use the [Run] section. See here – Preet Sangha Sep 20 '09 at 1:16

    4 Answers

    up vote185down voteaccepted

    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 ManagedInstallerClassas 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"
    shareimprove this answer

    Inno Setup的常用脚本

     分类:
    安装不同的目录:
    [Files]
    Source: "我的程序*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
    Source: "我的程序*"; DestDir: {cf}我的程序; Flags: ignoreversion recursesubdirs createallsubdirs
     
    开始菜单快捷方式: 
    [Icons]
    Name: "{group}我的程序名称"; Filename: "{app}我的程序.exe" ;WorkingDir: "{app}" 

    桌面快捷方式: 
    [Icons]
    Name: "{userdesktop}我的程序名称"; Filename: "{app}我的程序.exe"; WorkingDir: "{app}" 

    开始菜单卸载快捷方式: 
    [Icons]
    Name: "{group}{cm:UninstallProgram,我的程序}"; Filename: "{uninstallexe}" 

    安装完后选择运行: 
    [Run]
    Filename: "{app}我的程序.exe"; Description: "{cm:LaunchProgram,我的程序名称}"; Flags: nowait postinstall skipifsilent 

    安装完后自动运行: 
    [Run]
    Filename: "{app}我的程序.exe"; 

    在界面左下角加文字: 
    [Messages]
    BeveledLabel=你的网站名称 

    选择组件安装:(组件1的Flags: fixed为必须安装) 
    [Types] 
    Name: "full"; Description: "选择安装"; Flags: iscustom 
    [Components] 
    Name: 组件1文件夹; Description: 组件1名称; Types: full; Flags: fixed 
    Name: 组件2文件夹; Description: 组件2名称; Types: full 
    Name: 组件3文件夹; Description: 组件3名称; Types: full 
    [Files] 
    Source: "E:组件1文件夹我的程序.exe"; DestDir: "{app}"; Flags: ignoreversion 
    Source: "E:组件1文件夹*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 组件1文件夹 
    Source: "E:组件2文件夹*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 组件2文件夹 
    Source: "E:组件3文件夹*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 组件3文件夹 

    添加关于按钮: 
    [Code] 
    {注意:关于按钮单击后执行的过程,一定要写在InitializeWizard()过程之前} 
    procedure ButtonAboutOnClick(Sender: TObject); 
    begin 
    MsgBox('关于对话框。'+#13#10+'另起一行', mbInformation, MB_OK);//显示对话框 
    end; 
    {初始化安装向导时会触发的过程,这个过程的名字是INNO内部定义的,不能修改} 
    procedure InitializeWizard(); 
    begin 
    with TButton.Create(WizardForm) do//在WizardForm上面创建一个按钮 
    begin 
    Left := 32;//按钮距WizardForm左边的距离 
    Top := 302;//按钮距WizardForm上边的距离 
    Width := WizardForm.CancelButton.Width;//按钮的宽度,这里定义跟'取消'按钮等宽 
    Height := WizardForm.CancelButton.Height;//按钮的高度 
    Caption := '关于(&A)...';//按钮上的文字 
    Font.Name:='宋体';//按钮文字的字体 
    Font.Size:=9;//9号字体 
    OnClick := @ButtonAboutOnClick;//单击按钮触发的过程,就是前面的'ButtonAboutOnClick'过程,注意前面不要漏掉 
    Parent := WizardForm;//按钮的父组件,也就是按钮'载体',这里是WizardForm(安装向导窗体) 
    end; 
    end; 

    设置界面文字颜色: 
    [Code] 
    procedure InitializeWizard(); 
    begin 
    WizardForm.WELCOMELABEL1.Font.Color:= clGreen;//设置开始安装页面第一段文字的颜色为绿色 
    WizardForm.WELCOMELABEL2.Font.Color:= clOlive;//设置开始安装页面第二段文字的颜色为橄榄绿 
    WizardForm.PAGENAMELABEL.Font.Color:= clred;//设置许可协议页面第一段文字的颜色为红色 
    WizardForm.PAGEDESCRIPTIONLABEL.Font.Color:= clBlue; //设置许可协议页面第二段文字的颜色为蓝色 
    WizardForm.MainPanel.Color:= clWhite;//设置窗格的颜色为白色 
    end; 

    判断所选安装目录中原版主程序是否存在:
    [Code] 
    function NextButtonClick(CurPage: Integer): Boolean; 
    begin 
    Result:= true; 
    if CurPage=wpSelectDir then 
    if not FileExists(ExpandConstant('{app}主程序.exe')) then 
    begin 
    MsgBox('安装目录不正确!', mbInformation, MB_OK ); 
    Result := false; 
    end; 
    end;
     
     
    注:
    {app}表示默认安装路径为C:Program Files我的程序
    {cf}表示默认安装路径为C:Program FilesCommon Files我的程序

    颜色:
    clBlack(黑色),clMaroon(暗红),clGreen(绿色),clOlive(橄榄绿),clNavy(深蓝),clPurple(紫色),clTeal(深青),clGray(灰色),clSilver(浅灰),clRed(红色),clLime(浅绿),clYellow(黄色),clBlue(蓝色),clFuchsia(紫红),clAqua(青绿),clWhite(白色)。te(白色)。
    增加path路径:
    [Register]
    Root: HKLM; Subkey: "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerEnvironment"; ValueType: string; ValueName: "Path"; ValueData: "{olddata};{app}";Flags:uninsdeletekey
     

    0、调用DOS命令或批处理等其它命令行工具等

    Exec(ExpandConstant('{cmd}'), '/c dir c: >a.txt',ExpandConstant('{app}'), SW_SHOWNORMAL, ewNoWait, ResultCode);

    1、不显示一些特定的安装界面 
    [code]
    function ShouldSkipPage(PageID: Integer): Boolean; 
    begin 
    if PageID=wpReady then 
    result := true; 
    end;
    wpReady 是准备安装界面
    PageID查询 INNO帮助中的 Pascal 脚本: 事件函数常量
    预定义向导页 CurPageID 值
    wpWelcome, wpLicense, wpPassword, wpInfoBefore, wpUserInfo, wpSelectDir, wpSelectComponents, wpSelectProgramGroup, wpSelectTasks, wpReady, wpPreparing, wpInstalling, wpInfoAfter, wpFinished

    如果是自定义的窗体,则PageID可能是100,你可以在curPageChanged(CurPageID: Integer)方法中打印出到curpageid到底是多少。

    2、获取SQLserver安装路径
    var 
    dbpath:string;
    rtn:boolean;
    rtn := RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWAREMicrosoftMSSQLServerSetup','SQLPath', dbpath);
    if (!rtn) then dbpath := ExpandConstant('{app}');

    3、获取本机的IP地址
    ip:string;
    rtn:boolean;

    //{083565F8-18F0-4F92-8797-9AD701FCF1BF}视网卡而定见LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionNetworkCards处
    rtn :=RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEMCurrentControlSetServices{083565F8-18F0-4F92-8797-9AD701FCF1BF}ParametersTcpIp','IpAddress', ip);
    if (not rtn) or (ip='0.0.0.0') or (ip='') then ip := '127.0.0.1';

    4、检查数据库是否安装
    //检查是否已安装SQL
    try
        CreateOleObject('SQLDMO.SQLServer');
    except
        RaiseException('您还没有安装SQL数据库.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)');
    end;

    5、根据环境变量选择组件,获取系统环境变量值见方法6
    procedure CurPageChanged(CurPageID: Integer);
    var
    path:string;
    rtn:boolean;
    begin
    //MsgBox(inttostr(curpageid),mbInformation,mb_ok);
    if (curpageId =7) then
    begin
        rtn := checkTomcat6(path);
        if rtn then//如果系统以前没安装tomcat则选中组件,否则不选中
        begin
           WizardForm.ComponentsList.CheckItem(2,coUnCheck);
           WizardForm.ComponentsList.ItemEnabled[2] := false;
        end;
    end;
    end;

    6、系统环境变量操作
    读取:
    function GetEnv(const EnvVar: String): String;
    举例:GetEnv('java_home')
    设置:
    [Setup]
    ChangesEnvironment=true

    [code]
    //环境变量名、值、是否安装(删除)、是否所有用户有效
    procedure SetEnv(aEnvName, aEnvValue: string; aIsInstall: Boolean);//设置环境变量函数
    var
    sOrgValue: string;
    x,len: integer;
    begin
        //得到以前的值
        RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEMCurrentControlSetControlSession ManagerEnvironment', aEnvName, sOrgValue)
        sOrgValue := Trim(sOrgValue);
        begin
          x := pos( Uppercase(aEnvValue),Uppercase(sOrgValue));
          len := length(aEnvValue);
          if aIsInstall then//是安装还是反安装
          begin
              if length(sOrgValue)>0 then aEnvValue := ';'+ aEnvValue;
              if x = 0 then Insert(aEnvValue,sOrgValue,length(sOrgValue) +1);
          end
          else
          begin
             if x>0 then Delete(sOrgValue,x,len);
             if length(sOrgValue)=0 then 
             begin
               RegDeleteValue(HKEY_LOCAL_MACHINE, 'SYSTEMCurrentControlSetControlSession ManagerEnvironment',aEnvName);
               exit;
             end;
          end;
          StringChange(sOrgValue,';;',';');
          RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEMCurrentControlSetControlSession ManagerEnvironment', aEnvName, sOrgValue)
        end;
    end;

    7、获取NT服务安装路径

    Windows服务在系统安装后会在注册表的 "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices"下
    以服务的ServiceName建1个目录,
    目录中会有"ImagePath"

    举例获取tomcat6服务安装路径:
    RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEMCurrentControlSetServices omcat6','ImagePath', sPath);

    ------------------------------------------------------------------------
    算不上原创,可也花费了很多时间心血查资料、整理、调试

    Inno Setup 安装、卸载前检测进程或服务

     (2015-04-22 11:15:00)
    标签: 

    inno

     

    inno打包

     

    iss

     

    isapprunning

     

    psvince.dll

    分类: 编程
        在用Inno打包期间遇到了一些小问题,在这里总结一下:
     
    Inno.iss部分内容如下:

    1、32位程序的PSVince.dll插件方法。
    [Files]
    Source: psvince.dll; Flags: dontcopy
    
    [Code]
    function IsModuleLoaded(modulename: AnsiString ):  Boolean;
    external 'IsModuleLoaded@files:psvince.dll stdcall';
    
    
    2、PSVince控件在64位系统(Windows 7/Server 2008/Server 2012)下无法检测到进程,使用下面的函数可以解决。
    
    
    function IsAppRunning(const FileName : string): Boolean;
    var
        FSWbemLocator: Variant;
        FWMIService   : Variant;
        FWbemObjectSet: Variant;
    begin
        Result := false;
        try
          FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
          FWMIService := FSWbemLocator.ConnectServer('', 'rootCIMV2', '', '');
          FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
          Result := (FWbemObjectSet.Count > 0);
          FWbemObjectSet := Unassigned;
          FWMIService := Unassigned;
          FSWbemLocator := Unassigned;
        except
          if (IsModuleLoaded(FileName)) then
            begin
              Result := false;
            end
          else
            begin
              Result := true;
            end
          end;
    end;
    这里,有可能存在异常:Exception: SWbemLocator:依赖服务或组件无法启动
    解决办法参照如下步骤:
    
    
    1.在命令提示行运行以下命令:
        cd /d %windir%system32wbem 
        rename Repository Rep_bak 
    2.建一个.bat批处理文件并运行,内容如下: 
        Mofcomp C:WINDOWSsystem32WBEMcimwin32.mof
        Mofcomp C:WINDOWSsystem32WBEMcimwin32.mfl
        Mofcomp C:WINDOWSsystem32WBEMsystem.mof
        Mofcomp C:WINDOWSsystem32WBEMwmipcima.mof
        Mofcomp C:WINDOWSsystem32WBEMwmipcima.mfl
    3.在命令提示行运行以下命令:
        cd /d %windir%system32wbem 
        for %i in (*.mof,*.mfl) do Mofcomp %i 
    4.重新注册 WMI 组件,在命令提示行运行以下命令:
        cd /d %windir%system32wbem 
        for %i in (*.dll) do RegSvr32 -s %i 
        for %i in (*.exe) do %i /RegServer 
    
    
    //安装,并在安装前检测程序是否在运行,如果运行先结束进程
    function InitializeSetup(): Boolean;
    begin
      Result := true;
      if  IsAppRunning('{#MyAppExeName}') then
      begin
        if MsgBox('安装程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续安装;'#13''#13'单击“否”按钮退出安装!', mbConfirmation, MB_YESNO) = IDYES then
        begin
          TaskKillProcessByName('{#MyAppExeName}');
          Result:= true;
        end
        else
          Result:= false;
      end;
    end;
    //卸载,与安装类似
    
    
    function InitializeUninstall(): Boolean;
      begin
        Result:= true;
        if  IsAppRunning('{#MyAppExeName}') then
        begin
          if MsgBox('卸载程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续卸载;'#13''#13'单击“否”按钮退出卸载!', mbConfirmation, MB_YESNO) = IDYES then
          begin
            TaskKillProcessByName('{#MyAppExeName}');
            Result:= true;
          end
          else
            Result:= false;
        end;
      end;

     

  • 相关阅读:
    vue学习
    BBS登录注册技术点归纳
    BBS项目模态框的使用
    django后台管理系统
    java 之 jsp简介
    http 之 CORS简介
    web 之 session
    linux 之学习路线
    Ubuntu 之 win10更新ubuntu启动项消失
    Web 之 Cookie
  • 原文地址:https://www.cnblogs.com/micro-chen/p/6039863.html
Copyright © 2020-2023  润新知