【问题标题】:Detect and require a Windows QFE/patch for during installation在安装期间检测并要求 Windows QFE/补丁
【发布时间】:2012-03-17 16:37:59
【问题描述】:

我们的 WiX 安装程序将 .NET 4.0 WinForms 应用程序部署到 Windows Vista 和 7 桌面。该应用程序包含一个Portable Class Library,它需要一个.NET patch (KB2468871)。我们需要安装补丁作为先决条件。可以通过多种方式应用补丁:

  1. 下载 KB2468871 补丁并安装
  2. 安装Portable Library Tools
  3. 作为使用 ClickOnce 的先决条件(可能是 #1 的变体)

使用来自 a similar question 的建议,我创建了一个 CustomAction 来检查我演示的 QFE (#1),它在找到时返回 true。

private static bool IsPatchAlreadyInstalled()
{
    // If the patch is installed, we can find it using WMI
    var query = new SelectQuery("SELECT HotFixID FROM Win32_QuickFixEngineering WHERE HotFixID = 'Q2468871' OR HotFixID = 'KB2468871'");
    var results = new ManagementObjectSearcher(query).Get();
    return results.Count > 0;
}

不幸的是,这在我的开发机器上失败了,因为补丁是作为工具 (#2) 的一部分安装的。我还没有看到情况 #3。

检测补丁是否已应用的更好方法是什么?

【问题讨论】:

    标签: c# .net windows wix windows-installer


    【解决方案1】:

    Win32_QuickFixEngineering 不会返回所有更新。实际上,它只返回仅限于 QFE 的更新:

    由 Microsoft Windows Installer (MSI) 或 Windows 提供的更新 更新站点 (http://update.microsoft.com) 不返回 Win32_QuickFixEngineering。

    您所追求的更新是一个 MSI 补丁。使用 Microsoft.Deployment.WindowsInstaller(又名DTF - Deployment Tools FoundationWiX toolset 的一部分)查询应用的 MSI 补丁:

    public static bool IsPatchAlreadyInstalled(string productCode, string patchCode)
    {
        var patches = 
            PatchInstallation.GetPatches(null, productCode, null, UserContexts.Machine, PatchStates.Applied);
    
        return patches.Any(patch => patch.DisplayName == patchCode);
    }
    

    在这种情况下,KB2468871 是 .NET Framework 4 更新之一。如果机器上已应用更新,则以下内容将返回 true:

    IsPatchAlreadyInstalled("{F5B09CFD-F0B2-36AF-8DF4-1DF6B63FC7B4}", "KB2468871");// .NET Framework 4 Client Profile 64-bit
    IsPatchAlreadyInstalled("{8E34682C-8118-31F1-BC4C-98CD9675E1C2}", "KB2468871");// .NET Framework 4 Extended 64-bit
    IsPatchAlreadyInstalled("{3C3901C5-3455-3E0A-A214-0B093A5070A6}", "KB2468871");// .NET Framework 4 Client Profile 32-bit
    IsPatchAlreadyInstalled("{0A0CADCF-78DA-33C4-A350-CD51849B9702}", "KB2468871");// .NET Framework 4 Extended 32-bit
    

    【讨论】:

    • 我们正在验证这种方法。谢谢你的回答!
    【解决方案2】:

    我使用以下片段(使用来自@KMoraz 的产品代码)通过 WiX Burn 实现了这一点:

    <!-- KB2468871 update to support portable class libraries (PCL) on XP -->
    <Fragment>
      <!-- codes from http://stackoverflow.com/a/9506530 -->
      <util:ProductSearch ProductCode="{0A0CADCF-78DA-33C4-A350-CD51849B9702}" 
                          Variable="KB2468871_NET32_Installed" />
      <util:ProductSearch ProductCode="{8E34682C-8118-31F1-BC4C-98CD9675E1C2}" 
                          Variable="KB2468871_NET64_Installed" />
    
      <PackageGroup Id="NDP40_KB2468871_v2">
        <ExePackage Id="NDP40_KB2468871_v2_x86" Compressed="no" Vital="yes" Permanent="yes"
                    SourceFile="NDP40-KB2468871-v2-x86.exe"
                    DownloadUrl="http://download.microsoft.com/download/2/B/F/2BF4D7D1-E781-4EE0-9E4F-FDD44A2F8934/NDP40-KB2468871-v2-x86.exe"
                    DetectCondition="KB2468871_NET32_Installed"
                    InstallCondition="NOT VersionNT64"
                    InstallCommand="/q"/>
    
        <ExePackage Id="NDP40_KB2468871_v2_x64" Compressed="no" Vital="yes" Permanent="yes"
                    SourceFile="NDP40-KB2468871-v2-x86.exe"
                    DownloadUrl="http://download.microsoft.com/download/2/B/F/2BF4D7D1-E781-4EE0-9E4F-FDD44A2F8934/NDP40-KB2468871-v2-x64.exe"
                    DetectCondition="KB2468871_NET64_Installed"
                    InstallCondition="VersionNT64"
                    InstallCommand="/q"/>
      </PackageGroup>
    </Fragment>
    

    util 命名空间指的是Wix Util Extension。您需要在根元素中添加 xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" 并引用 WixUtilExtension.dll

    如果需要,安装程序将自动下载。您需要将安装程序文件本地保存在 WiX 项目的根目录中,其名称与 SourceFile 指定的名称相同,以便进行构建,但它们不会添加到安装包中,因为 Compressed 设置为 @ 987654328@.

    【讨论】:

      【解决方案3】:

      我一直在玩类似的情况,发现@KMoraz 的答案几乎是正确的。 (注意:@KMoraz,我会将此作为评论,但还没有代表!)

      Microsoft.Deployment.WindowsInstaller 命名空间似乎是可行的方法,但按产品代码过滤可能过于严格。我遇到了一个问题,补丁安装在机器上,但与产品代码{F5B09CFD-F0B2-36AF-8DF4-1DF6B63FC7B4}{8E34682C-8118-31F1-BC4C-98CD9675E1C2} 均无关。

      我的解决方案是改用 PatchInstallation.AllPatches,它返回系统上已安装补丁的未过滤列表,然后使用 linq 查找答案。

      public static bool CheckForPatch()
      {
          return IsPatchAlreadyInstalled("KB2468871")
      }
      
      public static bool IsPatchAlreadyInstalled(string patchCode)
      {
          var patches = PatchInstallation.AllPatches.ToList();
          patches.ForEach(x => Console.WriteLine("--found patch {0} for {1}",x.DisplayName,x.ProductCode));
          return patches.Any(patch => patch.DisplayName == patchCode);
      }
      

      样本输出:

      --found patch Microsoft Office 2010 Service Pack 1 (SP1) for {90140000-001F-0409-0000-0000000FF1CE}
      --found patch Update for Microsoft Office 2010 (KB2553270) 32-Bit Edition for {90140000-001F-0409-0000-0000000FF1CE}
      --found patch Microsoft Office 2010 Service Pack 1 (SP1) for {90140000-001F-0C0A-0000-0000000FF1CE}
      --found patch Update for Microsoft Office 2010 (KB2553270) 32-Bit Edition for {90140000-001F-0C0A-0000-0000000FF1CE}
      --found patch Microsoft Office 2010 Service Pack 1 (SP1) for {90140000-001F-040C-0000-0000000FF1CE}
      --found patch Update for Microsoft Office 2010 (KB2553270) 32-Bit Edition for {90140000-001F-040C-0000-0000000FF1CE}
      --found patch KB2533523 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2518870 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2656351 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2633870 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2468871 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2572078 for {3C3901C5-3455-3E0A-A214-0B093A5070A6}
      --found patch KB2533523 for {0A0CADCF-78DA-33C4-A350-CD51849B9702}
      --found patch KB2656351 for {0A0CADCF-78DA-33C4-A350-CD51849B9702}
      --found patch KB2468871 for {0A0CADCF-78DA-33C4-A350-CD51849B9702}
      --found patch KB2487367 for {0A0CADCF-78DA-33C4-A350-CD51849B9702}
      

      【讨论】:

      • 我只是针对 OP 的问题...无论如何,感谢您的帖子 - 我已经用 32 位 GUID 更新了它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      相关资源
      最近更新 更多