2012-02-28 24 views
15

Trình cài đặt WiX của chúng tôi triển khai ứng dụng .NET 4.0 WinForms cho Windows Vista và 7 máy tính để bàn. Ứng dụng bao gồm Portable Class Library yêu cầu .NET patch (KB2468871). Chúng ta cần phải cài đặt bản vá như là một điều kiện tiên quyết. Có nhiều cách khác nhau mà các bản vá có thể được áp dụng:Phát hiện và yêu cầu Windows QFE/vá trong khi cài đặt

  1. Tải bản vá KB2468871 và cài đặt nó
  2. Cài đặt Portable Library Tools
  3. Là một điều kiện tiên quyết sử dụng ClickOnce (có thể là một biến thể của # 1)

Sử dụng lời khuyên từ a similar question, tôi đã tạo một CustomAction để kiểm tra QFE (# 1) mà tôi đã trình bày trả về đúng khi được tìm thấy.

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; 
} 

Thật không may, lỗi này không được cài đặt như một phần của Công cụ (# 2). Tôi chưa chứng kiến ​​tình hình số 3.

Cách tốt hơn để phát hiện xem bản vá đã được áp dụng chưa?

Trả lời

13

Win32_QuickFixEngineering sẽ không trả lại tất cả các cập nhật. Trên thực tế, nó sẽ trả về chỉ cập nhật giới hạn QFE:

cập nhật được cung cấp bởi Microsoft Windows Installer (MSI) hoặc cập nhật trang web Windows (http://update.microsoft.com) không được trả về bởi Win32_QuickFixEngineering.

Bản cập nhật bạn sau là bản vá MSI. Sử dụng Microsoft.Deployment.WindowsInstaller (aka DTF - Deployment Tools Foundation, một phần của WiX toolset) để truy vấn các bản vá lỗi MSI áp dụng:

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); 
} 

Trong trường hợp này, KB2468871 là một trong .NET Framework 4 bản cập nhật. Các thông tin sau sẽ trả về true nếu các bản cập nhật đã được áp dụng trên máy:

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

Chúng tôi đang xác minh phương pháp này. Cảm ơn bạn vì câu trả lời! –

10

Tôi đã chơi xung quanh với một tình huống tương tự và thấy câu trả lời của @KMoraz gần như đúng. (LƯU Ý: @KMoraz, tôi sẽ để lại nhận xét này nhưng chưa có đại diện!)

Không gian tên Microsoft.Deployment.WindowsInstaller dường như là cách để đi, nhưng lọc theo mã sản phẩm có thể quá hạn chế. Tôi gặp sự cố khi bản vá được cài đặt trên máy nhưng không được liên kết với mã sản phẩm {F5B09CFD-F0B2-36AF-8DF4-1DF6B63FC7B4} hoặc {8E34682C-8118-31F1-BC4C-98CD9675E1C2}.

Giải pháp của tôi thay vì sử dụng PatchInstallation.AllPatches, trả về danh sách các bản vá đã cài đặt chưa được lọc trên hệ thống, sau đó tìm câu trả lời bằng LINQ.sản lượng

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); 
} 

mẫu:

--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

Tôi chỉ đang nhắm mục tiêu câu hỏi của OP ... Dù sao, cảm ơn bài đăng của bạn - Tôi đã cập nhật nó với GUID 32 bit. – KMoraz

+0

Đẹp. Câu trả lời của bạn có vẻ tốt và rất hữu ích. – jstromwick

10

Trong trường hợp bất cứ ai khác vẫn đang cố gắng để làm điều này vào năm 2015, tôi đạt được điều này với WiX Burn bằng cách sử dụng đoạn sau (bằng cách sử dụng mã sản phẩm từ @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> 

Không gian tên util tham chiếu đến Wix Util Extension. Bạn sẽ cần một xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" trong phần tử gốc của bạn và tham chiếu đến WixUtilExtension.dll.

Trình cài đặt sẽ tự động được tải xuống nếu được yêu cầu. Bạn cần lưu các tệp trình cài đặt được lưu cục bộ vào thư mục gốc của dự án WiX của bạn với cùng tên được chỉ định bởi SourceFile để xây dựng, nhưng chúng sẽ không được thêm vào nhóm thiết lập vì Compressed được đặt thành no.

Các vấn đề liên quan