2013-04-24 24 views
10

Tôi muốn giữ một tệp cấu hình khi trình cài đặt msi thực hiện nâng cấp lớn. Đối với tệp cấu hình, tôi thực hiện thay đổi khi cài đặt. Mã như sau:Làm thế nào để giữ một tập tin cấu hình khi nâng cấp lớn trong wix v3.8?

<Component Id="MODIFYCONFIG" Guid="6A1D7762-B707-4084-A01F-6F936CC159CE" Win64="yes"> 
    <File Id="Application.config" Name="Application.config" Vital="yes" KeyPath="yes" Source="Resource\Application.config"></File> 
    <util:XmlFile Id="SetValueIP" Action="setValue" Permanent="yes" File="[#Application.config]" 
     ElementPath="/configuration/applicationSettings/Application.Properties.Settings/setting[\[]@name='IpAddress'[\]]/value" Value="[IPADDRESS]" Sequence="1"/> 
    <util:XmlFile Id="SetValuePort" Action="setValue" Permanent="yes" File="[#Application.config]" 
     ElementPath="/configuration/applicationSettings/Application.Properties.Settings/setting[\[]@name='IpPort'[\]]/value" Value="[PORT]" Sequence="2"/> 
    <Condition>Not Installed</Condition> 
    </Component> 
    <Component Id="KEEPCONFIG" Guid="F7F173AA-C2FD-4017-BFBC-B81852A671E7" Win64="yes"> 
    <RemoveFile Id="ApplicationConfig" Name="Application.config" On="uninstall"/> 
    <Condition>(REMOVE=ALL) AND (NOT UPGRADINGPRODUCTCODE)</Condition> 
    </Component> 

Nhưng khi nâng cấp lớn xảy ra, tệp sẽ không được lưu giữ. Làm thế nào tôi có thể bảo quản tập tin đã sửa đổi?

Trả lời

9

Bạn có 3 lựa chọn khi nâng cấp:

  1. Tận dụng tập tin cấu hình phần vĩnh viễn. Điều này sẽ không bỏ cài đặt nó, và bạn sẽ có thể nâng cấp nó, nhưng loại bỏ nó sẽ rất khó khăn.
  2. Sử dụng Remember property pattern để lưu cài đặt cấu hình cho IP và PORT trong sổ đăng ký.
  3. Là một phần của quá trình cài đặt, hãy ghi tệp cấu hình vào tên tệp tạm thời và sau đó sử dụng lệnh CopyFile để tạo tệp đích. Khi nâng cấp kiểm tra tệp bằng FileSearch, và nếu nó tồn tại thì đừng sao chép. Chỉ vấn đề ở đây là nếu tệp cấu hình đã thay đổi, bạn sẽ không nhận được các phần được cập nhật.

Tùy chọn tốt nhất là ghi nhớ thuộc tính của tôi vì điều này có ít sự cố nhất.

+1

Bạn có thể tách thành phần khỏi tính tham chiếu bằng cách đặt GUID trống. Sau đó, các tập tin chỉ là dumped trên đĩa và sẽ được còn lại trên gỡ bỏ cài đặt. Sau đó, bạn có thể xóa sạch nó bằng cách sử dụng một hành động tùy chỉnh khi gỡ cài đặt hoặc chỉ để lại tệp được cài đặt khi gỡ cài đặt. Sau đó, cài đặt lại sẽ không cài đặt lại tệp trong trường hợp mặc định - tất cả các loại cạm bẫy. Bạn cần biết hành vi bạn muốn. –

2

Tôi mất một lúc, nhưng đây là cách tôi tự giải quyết nó. Nó có lẽ là một biến thể của tùy chọn thứ ba của Caveman_dick.

1) Thêm hành động mới vào UISequence để sao lưu tệp cấu hình hiện tại của bạn. Bạn có thể làm điều đó với sự kỳ diệu của hành động tùy chỉnh và ComponentSearch để thực sự xác định vị trí tệp.

2) Khôi phục tệp sau trong ExecuteSequence.

<Binary Id="CustomActions.CA.dll" SourceFile="..\CustomActions\bin\$(var.Configuration)\CustomActions.CA.dll" /> 
<CustomAction Id="BackupConfigFile" 
     Return="check" 
     BinaryKey="CustomActions.CA.dll" 
     DllEntry="BackupFile" /> 

<CustomAction Id="RestoreConfigFile" 
    Return="check" 
    Execute="deferred" 
    Impersonate="no" 
    BinaryKey="CustomActions.CA.dll" 
    DllEntry="RestoreFile" /> 

<CustomAction Id="PropertyDelegator" 
       Property="RestoreConfigFile" 
       Value="MYTARGET=[MYTARGET];FILENAME_TO_BACKUP=[FILENAME_TO_BACKUP]" /> 

<Property Id="FILENAME_TO_BACKUP" Value="test.exe.config" /> 

<Property Id="PREVIOUS_PATH"> 
    <ComponentSearch Id="evSearch" Guid="{010447A6-3330-41BB-8A7A-70D08ADB35E4}" /> 
</Property> 

và đây là CustomAction.cs nhanh chóng tôi đã viết:

[CustomAction] 
public static ActionResult BackupFile(Session session) 
{ 
    try 
    { 
     // check out if the previous installation has our file included 
     // and if it does, 
     // then make copy of it. 
     var previousInstallationPath = session["PREVIOUS_PATH"]; 
     var fileToBackup = session["FILENAME_TO_BACKUP"]; 

     if (!string.IsNullOrEmpty(previousInstallationPath) && !string.IsNullOrEmpty(fileToBackup)) 
     { 
      var absolutePath = Path.Combine(previousInstallationPath, fileToBackup); 
      if (File.Exists(absolutePath)) 
      { 
       var destinationPath = Path.Combine(Path.GetTempPath(), 
        string.Concat(fileToBackup, _MODIFIER)); 

       File.Copy(absolutePath, destinationPath); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     session.Log("Couldn't backup previous file: {0}", e); 
    } 
    return ActionResult.Success; 
} 

[CustomAction] 
public static ActionResult RestoreFile(Session session) 
{ 
    try 
    { 
     // check if our CustomAction made backup of file, 
     // and if it indeed exists in temp path, then 
     // we basically copy it back. 
     var currentInstallationPath = session.CustomActionData["MYTARGET"]; 
     var fileToRestore = session.CustomActionData["FILENAME_TO_BACKUP"]; 
     var fileOriginalContentPath = Path.Combine(Path.GetTempPath(), 
      string.Concat(fileToRestore, _MODIFIER)); 

     if (File.Exists(fileOriginalContentPath)) 
     { 
      var destinationFile = Path.Combine(currentInstallationPath, fileToRestore); 
      if (File.Exists(destinationFile)) 
       File.Delete(destinationFile); 

      File.Move(fileOriginalContentPath, destinationFile); 
     } 
    } 
    catch (Exception e) 
    { 
     session.Log("Couldn't restore previous file: {0}", e); 
    } 
    return ActionResult.Success; 
} 

để thực sự xác định trình tự:

<InstallUISequence> 
    <Custom Action="BackupConfigFile" After="AppSearch"></Custom> 
</InstallUISequence> 

<InstallExecuteSequence> 
    <Custom Action="PropertyDelegator" Before="RestoreConfigFile" /> 
    <Custom Action="RestoreConfigFile" After="InstallFiles"></Custom> 
</InstallExecuteSequence> 

đã không kiểm tra nó kỹ lưỡng, nhưng dường như làm công việc cho hiện nay. Caveat: Temp thư mục có thể thay đổi ?!

Ngoài ra còn có cái này mà tôi tìm thấy từ Internet, nhưng chưa thử nghiệm nó.

  <!-- Support Upgrading the Product --> 

      <Upgrade Id="{B0FB80ED-249E-4946-87A2-08A5BCA36E7E}"> 

        <UpgradeVersion Minimum="$(var.Version)" 
OnlyDetect="yes" Property="NEWERVERSIONDETECTED" /> 

        <UpgradeVersion Minimum="0.0.0" 
Maximum="$(var.Version)" IncludeMinimum="yes" 

              IncludeMaximum="no" 
Property="OLDERVERSIONBEINGUPGRADED" /> 

      </Upgrade> 

      <Property Id="OLDERVERSIONBEINGUPGRADED" Secure="yes" /> 



      <!-- Action to save and Restore the Config-File on reinstall 
--> 

      <!-- We're using CAQuietExec to prevent DOS-Boxes from 
popping up --> 

      <CustomAction Id="SetQtCmdLineCopy" Property="QtExecCmdLine" 
Value="&quot;[SystemFolder]cmd.exe&quot; /c copy 
&quot;[INSTALLDIR]MyApp.exe.config&quot; 
&quot;[INSTALLDIR]config.bak&quot;" /> 

      <CustomAction Id="QtCmdCopy" BinaryKey="WixCA" 
DllEntry="CAQuietExec" Execute="immediate" /> 

      <CustomAction Id="SetQtCmdLineRestore" 
Property="QtCmdRestore" Value="&quot;[SystemFolder]cmd.exe&quot; /c move 
/Y &quot;[INSTALLDIR]config.bak&quot; 
&quot;[INSTALLDIR]MyApp.exe.config&quot;" /> 

      <CustomAction Id="QtCmdRestore" Execute="commit" 
BinaryKey="WixCA" DllEntry="CAQuietExec" /> 



      <!-- These actions will run only for a major upgrade --> 

      <InstallExecuteSequence> 

        <Custom Action="SetQtCmdLineCopy" 
After="InstallInitialize"> NOT (OLDERVERSIONBEINGUPGRADED = "")</Custom> 

        <Custom Action="QtCmdCopy" 
After="SetQtCmdLineCopy">NOT (OLDERVERSIONBEINGUPGRADED = "")</Custom> 

        <Custom Action="SetQtCmdLineRestore" 
Before="InstallFinalize">NOT (OLDERVERSIONBEINGUPGRADED = "")</Custom> 

        <Custom Action="QtCmdRestore" 
After="SetQtCmdLineRestore">NOT (OLDERVERSIONBEINGUPGRADED = 
"")</Custom> 

      </InstallExecuteSequence> 
11

Tệp cấu hình này được giải quyết cho tôi ... được giữ nguyên với nâng cấp nhỏ/lớn và hoàn toàn bị xóa khi gỡ cài đặt.

Ref: http://blogs.msdn.com/b/astebner/archive/2008/10/19/9006538.aspx

EDIT: Tóm tắt thông tin từ các trang liên kết ...

  1. Mỗi tập tin cấu hình có trách nhiệm đó là thành phần riêng, nơi mà các tập tin cấu hình được đánh dấu như keypath của các thành phần . Logic thay thế tệp không phiên bản sẽ được Trình cài đặt Windows sử dụng.
  2. Thêm hành động "RemoveExistingProducts" sau hành động "InstallFiles". Phiên bản mới của tất cả các thành phần được cài đặt trước khi tháo MSI cũ. Khi nó được thực hiện trong chuỗi này, các thành phần sẽ có số tham chiếu của chúng tăng lên 2, nhưng các tệp cấu hình sẽ không được thay thế trừ khi chúng chưa được sửa đổi (vì logic thay thế tệp không phiên bản). Khi MSI cũ bị xóa, số lượng tham chiếu sẽ bị giảm xuống 1, nhưng các tệp sẽ không bị xóa vì số lượng tham chiếu không phải là 0,
+0

Có, công trình này và là lựa chọn tốt nhất. Bạn cần phải tuân thủ tất cả các quy tắc thành phần và tham chiếu hoặc tệp có thể bị thiếu sau khi nâng cấp chính. Bạn cũng có thể bảo vệ tệp cấu hình bằng cách đặt thành phần cố định và sau đó sử dụng một hành động tùy chỉnh được điều chỉnh để chỉ chạy khi gỡ cài đặt mà không phải là một phần của bản nâng cấp lớn để xóa khi thực hiện gỡ cài đặt thực. Điều kiện UPGRADINGPRODUCTCODE có thể được sử dụng để phát hiện nếu nâng cấp lớn đang được thực hiện. Chỉ để lại điều này để tham khảo cho bất cứ ai có thể phải đối mặt với cùng một vấn đề. –

+0

Liên kết có giá trị rất tốt, nhưng tôi nghĩ sẽ tốt hơn nếu tóm tắt bài đăng chỉ trong trường hợp nó biến mất. – knightpfhor

+0

Phần 2 có vẻ sai. Nhận được thông báo lỗi, khi thêm hành động "RemoveExistingProducts" sau "InstallFiles": Một số hành động nằm giữa InstallInitialize và RemoveExistingProducts. – Simon

1

Có một tùy chọn khác, nhưng có thể không áp dụng được cho kịch bản của bạn - tất cả phụ thuộc vào ai là ban đầu chạy trình cài đặt của bạn ...

Nếu ứng dụng của bạn được tải xuống trên web chẳng hạn, chúng tôi thường đi với mẫu thuộc tính nhớ của caveman_dick.

Tuy nhiên, chúng tôi có một vài bộ sản phẩm luôn được nhân viên cài đặt của chúng tôi cài đặt, truy cập trang web của khách hàng. Trong trường hợp này, chỉ đơn giản là không bao gồm tập tin cấu hình trong trình cài đặt!

Đặt đơn giản - nếu trình cài đặt không biết về tệp, khi đó trình cài đặt sẽ không gỡ cài đặt nó!

Trong trường hợp này, bạn có tùy chọn nhóm cài đặt của bạn tạo và định cấu hình tệp cấu hình hoặc ứng dụng của bạn khi nó không tồn tại và hỏi người dùng về các giá trị.

Như đã nêu, đây sẽ không phải là một tùy chọn trong một số trường hợp, nhưng nó hoạt động tốt cho chúng tôi.

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