【问题标题】:How can I include KB2670838 in an installer with InstallShield 2013?如何在 InstallShield 2013 安装程序中包含 KB2670838?
【发布时间】:2017-02-19 17:08:06
【问题描述】:

我正在使用 InstallShield 2013 为需要 Windows Platform Update KB2670838 的应用程序制作基本 MSI 安装程序。

对于 .NET 框架和其他要求,我在 InstallShield 的 Redistributables 部分中选择它们。 KB2670838 不可用。

如果我从 Microsoft 下载 KB2670838,我会得到一个 .msu 文件。是否可以以某种方式将其包含在安装程序中,以便在需要时自动安装?如果没有,有没有办法停止安装并告诉用户“需要 KB2670838 但未安装。在此处获取...”?

【问题讨论】:

  • shoelzer:请再次查看我的 MSI 建议。我不会使用 PSInfo,而是使用文件搜索来确保您的设置未来的可靠性。
  • @Glytzhkof 你的回答充满了有用的信息,肯定有帮助,但没有完全回答我问的问题。 “先决条件”或“包”是我需要知道的。这就是为什么我赞成你的答案但接受了迈克尔的答案。
  • 好的。我不会在我自己的包中包含 Windows 修补程序,这就是我回答的原因。与此修补程序可能在某个时候被弃用有关,并且它通常安装在目标系统上,或者由于公司政策明确禁止安装。
  • @Glytzhkof 好点。那么如何让 InstallShield 中止并给用户一个好消息,让他们知道该怎么做?

标签: powershell windows-installer wmi installshield hotfix


【解决方案1】:

在 InstallShield 中,您通常应该将此类更新作为先决条件(工具 > 先决条件编辑器)或作为套件中包含的包提供(参考 [SystemFolder]wusa.exe 以安装 .msu 文件)。在这两种情况下,这都会使可再发行安装在逻辑上与您的软件包安装分开,同时为您的用户提供单一的安装体验。

Glytzhkof 提到了几个关于如何确定是否已安装更新的非常好的观点。您将希望将这些合并到您的条件中(在先决条件或套件包上),并且还需要检测您的 .msi 包中的更新或缺少更新,以便如果在 @ 时尚未安装所需的更新,它可以中止987654324@上线了。

【讨论】:

  • 同意 Michael 的一切,除了安装是 Microsoft 安全修补程序或以其他方式通过 Windows 更新交付的情况。然后我会让安装程序了解先决条件,中止安装程序并强制它们通过 Windows 更新进行更新。造成这种情况的原因很多,但最重要的是公司政策。某些修补程序有时无法在公司中安装,以避免破坏自定义网络软件和类似的东西。
  • 另一个原因是该修补程序最终可能会在某个时候被弃用,如果所有文件更新都已完成,安装程序仍应允许安装。
【解决方案2】:

注册表中的添加/删除程序列表可以帮助您大致了解已安装的内容:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

这似乎没有提供已安装内容的完整列表:http://social.technet.microsoft.com/Forums/windows/en-US/d913471a-d7fb-448d-869b-da9025dcc943/where-does-addremove-programs-get-its-information-from-in-the-registry?forum=w7itprogeneral

另一种方法可能是使用知识库文章中的文件信息: http://support.microsoft.com/kb/2670838/en(更多信息:文件信息)并使用 WIX / MSI 的 AppSearch / LaunchCondition 功能。这应该可以解决问题,尽管我发现语法有点违反直觉。

另一种方法是编写一个自定义操作并结合这两个来源(添加/删除条目和文件信息)。这样的自定义操作不会对系统进行任何更改,因此比导致回滚问题的其他自定义操作问题更少。我发现测试和维护自定义操作更容易,以防在某些时候需要进一步的先决条件。不过,这是一个口味问题。我只是发现针对选择的文件运行先决条件脚本以测试它是否正确识别它们并按预期运行比为每个测试继续运行 MSI 文件更容易。

这是一个类似的问题,来自 superuser.com 的一些指针: https://superuser.com/questions/521175/determine-if-windows-hotfix-has-been-applied

还有另一个指向 serverfault.com(系统管理站点)的链接。使用 PowerShell 的好方法当然可以迁移到自定义操作: https://serverfault.com/questions/312778/determine-if-user-has-hotfix-981889-installed

更多涉及 update.exe、WMI 和 Powershell 脚本以查看所有已安装的修补程序的 serverfault.com 内容: https://serverfault.com/questions/263847/how-can-i-query-my-system-via-command-line-to-see-if-a-kb-patch-is-installed 。 推荐阅读。微软:http://technet.microsoft.com/en-us/library/hh849836.aspx

PSInfo 似乎能够显示已安装的修补程序:http://technet.microsoft.com/en-us/sysinternals/bb897550

【讨论】:

    【解决方案3】:

    @Glytzhkof 好点。那么如何让 InstallShield 中止并给用户一个好消息,让他们知道该怎么做呢? – shoelzer 1 小时前

    然后我将添加一个新答案 - 太长了,无法在评论中写。

    • 在“更多信息”下找到您需要扫描的文件详细信息 信息:文件信息”在这篇 kdb 文章中: http://support.microsoft.com/kb/2670838/en
    • 选择一些要扫描的文件并在 Installshield 中添加为文件搜索(见下面的屏幕截图)。您为每个文件(FILE1FOUND、FILE2FOUND、FILE3FOUND 等)指定一个属性,如果搜索与文件详细信息(版本、大小、日期等)匹配,则该属性设置为文件的完整路径文件。否则,该属性未定义或设置为默认值(屏幕截图显示预定义搜索,而不是文件搜索,但您明白了)。
    • 最后,您为每个文件添加LaunchCondition 条目,以确保您选择检查的所有文件都是正确的版本或更高版本。我想这是在先决条件或类似情况下 - 我不记得了。打开已编译的 MSI 并检查它是否看起来像 LaunchConditon table。

    记录在案:(不属于上述建议)

    我个人赞成为这样的复杂逻辑编写单个脚本,以确保可以在 MSI 文件之外作为一个整体检查逻辑并作为一个整体进行关键测试。将 cmets 添加到此类代码以解释脚本正在检查的内容以及原因(有助于企业部署)也很好。一个脚本可以直接在机器上运行几十个测试,而无需重新编译 MSI。如果逻辑复杂,这可以节省大量时间。如果您编写已编译的 dll,您可以显示一个消息框并将 Visual Studio 调试器附加到 msiexec.exe 进程(客户端或服务器,具体取决于您的自定义操作在哪个上下文中运行),并在嵌入 MSI 时单步执行代码,但这似乎超出了您的方案的范围。只是想为可能阅读本文的其他人提及它。另请查看 Stefan Kruger 的installsite.com,了解有关此类复杂设置调试的更多信息。

    请务必注意,通常不建议在脚本对系统进行更改的情况下使用脚本编写 - 如果有内置的 MSI 方法可以实现相同的结果。这样做的原因是,对机器进行更改的脚本将需要为其指定单独的回滚操作,以便 MSI 遵循最佳实践。要做到正确,这可能需要大量的工作和复杂性。上面的脚本只会检查系统条件,所以不需要回滚支持。

    【讨论】:

    • 感谢您回来回答这个问题。这正是我所需要的。
    • 没问题,在回答您的问题之前,我在其他答案中添加了太多信息,但希望其余部分对其他人有用。
    【解决方案4】:

    让我尝试添加一个参考风格的答案,因为我的其他答案在这一点上至少可以说有点有机 - 我将保留它,因为它包含一个 MSI 讨论。 请参阅下方中间部分的 MSI 建议:

    WMI:

    wmic qfe where "HotfixID = 'KB973687'"
    

    PowerShell:(只需获取完整列表的修补程序)

    get-hotfix | findstr "981889"
    

    SystemInfo(删除列表格式的参数):

    systeminfo /fo csv
    

    PSInfo(好像没有列出所有机器上的所有东西,可能无法正常静默运行):

    PSinfo -h
    

    注册表(显然不是完整的修补程序列表):

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    

    对于 MSI 自定义操作使用,我实际上会使用一个自定义操作来检查文件版本,如我的其他答案中所述。非常可靠,并且考虑到在文件仍然是最新的情况下可能会弃用修补程序。


    参考文献:

    【讨论】:

      【解决方案5】:

      遇到了同样的问题,并通过添加 PowerShell 脚本的先决条件和执行它的批处理文件来解决。

      pre.ps1 文件如下所示:

      function TestConnection
      {
          Test-Connection -ComputerName "8.8.8.8" -Quiet
      }
      
      get-hotfix -id KB2670838
      if(!$?){
          #SourceURI = "https://download.microsoft.com/download/1/4/9/14936FE9-4D16-4019-A093-5E00182609EB/Windows6.1-KB2670838-x64.msu";
          #$FileName = $SourceURI .Split('/')[-1]
          #$BinPath = Join-Path $DownloadPath -ChildPath $FileName
          Invoke-Webrequest -Uri $SourceURI -OutFile $BinPath
          #Start-Process -FilePath $BinPath -ArgumentList "/q /norestart" -Wait -NoNewWindow
      }
      

      pre.cmd 文件如下所示:

      @echo off
      ::set PS_FILE=%~dp0Prerequisite.ps1
      set PS_FILE=%~dpn0.ps1
      set PS_EXEC_PATH=%SystemRoot%\sysnative\WindowsPowerShell\v1.0\
      set PS_EXEC_PATH=%SystemRoot%\System32\WindowsPowerShell\v1.0\
      ::set PS_EXEC_PATH=%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\
      set PS_EXEC_PATH=
      set PS_EXEC=%PS_EXEC_PATH%powershell.exe
      echo %PS_EXEC%
      echo %PS_FILE%
      
      ::%PS_EXEC% -file %PS_FILE% set-executionpolicy remotesigned
      ::%PS_EXEC% -NoProfile -ExecutionPolicy Bypass -Command "& '%PS_FILE%'"
      ::This is with admin rights
      %PS_EXEC% -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%PS_FILE%""' -Verb RunAs}"
      
      ::pause
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 2018-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多