Envpr 2023-01-31 15:10 采纳率: 100%
浏览 19
已结题

开发安装包怎么可以分开安装程序和组件,然后组件相关文件可以单独卸载、更新

为主程序写了一些小组件,为方便现场更新,需要打成安装包,目前都是给zip直接解压替换,想要用Inno Setup之类的软件开发个安装程序,方便升级组件,或者是直接整合到大的安装包里,可以勾选组件升级,但是没找到对应功能的实现方式,求各位帮忙/抱拳

  • 写回答

1条回答 默认 最新

  • m0_54204465 2023-01-31 15:53
    关注

    通过使用安装程序制作工具,比如Inno Setup,你可以将主程序和组件打包分开,并在安装程序中提供勾选选项,供用户选择是否安装组件。在安装程序中,你可以通过预先设定组件安装路径的方式,控制组件的卸载和更新。

    具体实现方法:

    使用安装程序制作工具(如Inno Setup)创建一个安装程序项目,并将主程序作为主安装项。
    将组件打包为一个单独的文件,并在安装程序项目中添加一个可选的组件项。
    在安装程序代码中,为组件设定一个固定的安装路径,并通过代码控制其卸载和更新。
    以Inno Setup为例,你可以使用以下代码控制组件的卸载:

    [Code]
    function Uninstall: Boolean;
    begin
    Result := True;
    if IsComponentSelected('组件项的名称') then
    begin
    if not RemoveDirectory(ExpandConstant('{app}\组件安装路径')) then
    begin
    MsgBox('无法卸载组件,请重试。', mbError, MB_OK);
    Result := False;
    end;
    end;
    end;
    [/Code]
    

    以上代码通过调用IsComponentSelected函数判断用户是否选择了该组件,如果选择了则调用RemoveDirectory函数删除组件安装路径中的文件。

    关于Inno Setup

    [Setup]
    AppName=My App
    AppVersion=1.0.0
    DefaultDirName={pf}\My App
    
    [Files]
    Source: "MyApp.exe"; DestDir: "{app}"
    Source: "MyAppComponent.dll"; DestDir: "{app}"; Flags: external
    
    [Code]
    procedure UpdateMyAppComponent();
    var
    ResultCode: Integer;
    begin
    ResultCode := MsgBox('Do you want to update MyAppComponent?', mbConfirmation, MB_YESNO);
    if ResultCode = IDYES then
    begin
    if Exec('MyAppComponentUpdater.exe', '', '', SW_SHOW, ewWaitUntilTerminated,
    ResultCode) then
    begin
    MsgBox('MyAppComponent has been updated successfully!', mbInformation, MB_OK);
    end
    else
    begin
    MsgBox('Failed to update MyAppComponent!', mbError, MB_OK);
    end;
    end;
    end;
    
    [Setup]
    AppName=My App
    AppVersion=1.0.0
    DefaultDirName={pf}\My App
    
    [Files]
    Source: "MyApp.exe"; DestDir: "{app}"
    Source: "MyAppComponent.dll"; DestDir: "{app}"; Flags: external
    
    [Code]
    procedure UpdateMyAppComponent();
    var
    ResultCode: Integer;
    begin
    ResultCode := MsgBox('Do you want to update MyAppComponent?', mbConfirmation, MB_YESNO);
    if ResultCode = IDYES then
    begin
    if Exec('MyAppComponentUpdater.exe', '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
    begin
    MsgBox('MyAppComponent has been updated successfully!', mbInformation, MB_OK);
    end
    else
    begin
    MsgBox('Failed to update MyAppComponent!', mbError, MB_OK);
    end;
    end;
    end;
    
    

    在这个例子中,Inno Setup会将MyApp.exe和MyAppComponent.dll两个文件安装到指定目录。在安装过程中,用户可以选择是否更新MyAppComponent.dll。如果用户选择了更新,Inno Setup会调用MyAppComponentUpdater.exe程序,用来升级MyAppComponent.dll。

    Inno Setup实现单独安装组件的代码

    ;Inno Setup Script
    [Setup]
    AppName=My Application
    AppVersion=1.0
    DefaultDirName={pf}\My Application
    DefaultGroupName=My Application
    UninstallDisplayIcon={app}\MyApp.exe
    
    [Files]
    Source: "MyApp.exe"; DestDir: "{app}"
    Source: "ComponentA.dll"; DestDir: "{app}"
    Source: "ComponentB.dll"; DestDir: "{app}"
    
    [Components]
    Name: "Main Application"; Description: "Main Application Files"; Types: full custom
    Name: "ComponentA"; Description: "ComponentA Files"; Types: custom; Flags: exclusive
    Name: "ComponentB"; Description: "ComponentB Files"; Types: custom; Flags: exclusive
    
    [Code]
    var
      ComponentA: TNewCheckBox;
      ComponentB: TNewCheckBox;
    
    procedure InitializeWizard;
    begin
      ComponentA := TNewCheckBox.Create(WizardForm);
      ComponentA.Parent := WizardForm.SelectComponentsPage;
      ComponentA.Left := ScaleX(8);
      ComponentA.Top := ScaleY(248);
      ComponentA.Width := ScaleX(100);
      ComponentA.Caption := 'ComponentA';
    
      ComponentB := TNewCheckBox.Create(WizardForm);
      ComponentB.Parent := WizardForm.SelectComponentsPage;
      ComponentB.Left := ScaleX(8);
      ComponentB.Top := ScaleY(268);
      ComponentB.Width := ScaleX(100);
      ComponentB.Caption := 'ComponentB';
    end;
    
    procedure CurStepChanged(CurStep: TSetupStep);
    begin
      if CurStep = ssPostInstall then
      begin
        if ComponentA.Checked then
          ExtractTemporaryFile('ComponentA.dll');
        if ComponentB.Checked then
          ExtractTemporaryFile('ComponentB.dll');
      end;
    end;
    
    

    这段代码实现了组件单独安装的功能,在安装程序启动后,用户可以选择要安装的组件,选择后再进行安装。

    使用Inno Setup实现主程序与组件分开安装的示例:

    [Setup]
    AppName=My Program
    AppVersion=1.0
    DefaultDirName={pf}\My Program
    
    [Files]
    Source: "MyProgram.exe"; DestDir: "{app}"
    Source: "Component1.dll"; DestDir: "{app}"
    Source: "Component2.dll"; DestDir: "{app}"
    
    [Components]
    Name: "Component1"; Description: "This is component 1"
    Name: "Component2"; Description: "This is component 2"
    
    [Component1]
    Source: "Component1.dll"; DestDir: "{app}"
    
    [Component2]
    Source: "Component2.dll"; DestDir: "{app}"
    
    

    通过上面的代码,安装程序将会创建两个可选的组件,可以单独选择安装或更新。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 2月9日
  • 已采纳回答 2月1日
  • 创建了问题 1月31日

悬赏问题

  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!