2012-02-28 30 views
15

我們的WiX安裝程序將.NET 4.0 WinForms應用程序部署到Windows Vista和7臺桌面。該應用程序包括一個Portable Class Library,需要.NET patch(KB2468871)。我們需要安裝該補丁程序作爲先決條件。有跡象表明,該補丁可應用於多種方式:在安裝過程中檢測並需要Windows QFE /補丁

  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。

什麼是檢測補丁是否已被應用的更好方法?

回答

13

Win32_QuickFixEngineering不會返回所有更新。事實上,它返回僅限於QFE更新:由Microsoft Windows安裝程序(MSI)或Windows 更新網站(http://update.microsoft.com)不被 Win32_QuickFixEngineering返回提供

更新。

您要更新的是MSI補丁。使用Microsoft.Deployment.WindowsInstaller(又名DTF - Deployment Tools Foundation,則WiX 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 
+0

我們正在驗證這種方法。謝謝您的回答! – 2012-03-01 20:49:44

10

我一直在玩弄類似的情況,發現@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} 
+0

我只是針對OP的問題...無論如何,感謝您的文章 - 我已經用32位GUID進行了更新。 – KMoraz 2012-03-06 17:55:31

+0

不錯。你的答案看起來不錯,而且非常有幫助。 – jstromwick 2012-03-06 18:22:11

10

萬一別人還在試圖做到這一點在2015年,我實現了這個與維克斯刻錄使用下面的片段(使用@KMoraz產品代碼):

<!-- 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設置爲no