Tôi có thể kiểm soát vị trí cài đặt người dùng .NET để tránh mất cài đặt khi nâng cấp ứng dụng không?


104

Tôi đang cố gắng tùy chỉnh vị trí của user.configtệp. Hiện nó được lưu trữ với mã băm và số phiên bản

%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\

Tôi muốn nó không phù hợp với phiên bản của ứng dụng

%AppData%\[CompanyName]\[ProductName]\

Điều này có thể được thực hiện và làm thế nào? Những tác động là gì? Người dùng có bị mất cài đặt của họ từ phiên bản trước sau khi nâng cấp không?


Mặc dù câu trả lời của uzbone có nhiều thông tin liên quan đến vị trí tệp, tôi tin rằng câu trả lời của Ian đúng hơn liên quan đến việc nâng cấp.
Anthony Mastrean

4
@AnthonyMastrean Cá nhân tôi nghĩ rằng bất kỳ cài đặt quan trọng nào không nên dựa vào cơ sở hạ tầng ApplicationSettings do Microsoft của tôi cung cấp. Muxa chỉ nên lưu trữ các cài đặt ở %AppData%\[CompanyName]/[ProductName]nơi chúng ta có thể tin tưởng rằng nó sẽ vẫn còn.
Ian Boyd

2
Không nghi ngờ gì nữa, trải nghiệm liên tục của tôi với ứng dụng cài sẵn và cài đặt người dùng thật tồi tệ. Tôi đề xuất các tệp json trong dữ liệu ứng dụng hoặc dữ liệu chương trình.
Anthony Mastrean

Bạn cũng có thể lưu trữ cài đặt của mình trong sổ đăng ký. Xem stackoverflow.com/a/12127888/1273550 để triển khai lớp cài đặt thay thế.
Ravi Patel

Câu trả lời:


39

Để trả lời câu hỏi đầu tiên, về mặt kỹ thuật, bạn có thể đặt tệp ở bất cứ đâu bạn muốn, tuy nhiên bạn sẽ phải tự viết mã nó, vì vị trí mặc định mà tệp đi đến là nơi đầu tiên trong hai ví dụ của bạn. ( liên kết đến cách tự làm )

Đối với câu hỏi thứ hai, nó phụ thuộc vào cách bạn triển khai ứng dụng. Nếu bạn triển khai qua .msi, thì có hai hàm băm trong thuộc tính của dự án thiết lập (mà msi được xây dựng từ đó), 'mã nâng cấp' và 'mã sản phẩm'. Những điều này xác định cách msi có thể được cài đặt và nếu nó nâng cấp, ghi đè hoặc cài đặt bên cạnh bất kỳ phiên bản nào khác của cùng một ứng dụng.

Ví dụ: nếu bạn có hai phiên bản phần mềm của mình và chúng có mã 'nâng cấp' khác nhau, thì đối với windows, chúng là những phần mềm hoàn toàn khác nhau bất kể tên là gì. Tuy nhiên, nếu mã 'nâng cấp' giống nhau, nhưng mã 'sản phẩm' khác thì khi bạn cố gắng cài đặt lần thứ 2, msi sẽ hỏi bạn có muốn nâng cấp hay không, lúc đó nó phải sao chép các giá trị từ cấu hình cũ sang cấu hình mới. Nếu cả hai giá trị đều giống nhau và số phiên bản không thay đổi thì cấu hình mới sẽ ở cùng vị trí với cấu hình cũ và nó sẽ không phải làm gì cả. Tài liệu MSDN

ClickOnce hơi khác một chút, vì nó dựa nhiều hơn vào phiên bản ClickOnce # và đường dẫn URL, tuy nhiên, tôi nhận thấy rằng miễn là bạn tiếp tục 'Xuất bản' lên cùng một vị trí, phiên bản mới của ứng dụng sẽ tiếp tục sử dụng cấu hình hiện có. ( liên kết đến cách ClickOnce xử lý các bản cập nhật )

Tôi cũng biết có một cách để hợp nhất các cấu hình theo cách thủ công trong quá trình cài đặt msi bằng cách sử dụng các tập lệnh cài đặt tùy chỉnh, nhưng tôi không nhớ các bước chính xác để thực hiện điều đó ... (xem liên kết này để biết cách thực hiện với web. cấu hình)


Mã nâng cấp không phải là mã được cho là không đổi và mã sản phẩm là mã phải thay đổi giữa các bản phát hành? blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx
estanford

Doh! bạn là chính xác, không thể tin được rằng tôi có một trong những ngược lại (và mất 2 năm để nắm bắt nó). Nó giống như ký tên

Điều đó có nghĩa là chỉ người dùng cài đặt mới được nâng cấp cài đặt của họ?
Micha Wiedenmann

79

Tôi muốn thêm văn bản được trích dẫn này làm tài liệu tham khảo khi tôi gặp vấn đề này trong tương lai. Giả sử bạn có thể hướng dẫn cơ sở hạ tầng ApplicationSettings sao chép cài đặt từ phiên bản trước bằng cách gọi Nâng cấp :

Properties.Settings.Value.Upgrade();

Từ bài đăng trên blog Câu hỏi thường gặp về Cài đặt Máy khách : ( lưu trữ )

Hỏi: Tại sao có số phiên bản trong đường dẫn user.config? Nếu tôi triển khai một phiên bản ứng dụng mới của mình, người dùng sẽ không mất tất cả các cài đặt được lưu bởi phiên bản trước đó chứ?

Đ: Có một số lý do khiến đường dẫn user.config nhạy cảm với phiên bản.

(1) Để hỗ trợ triển khai song song các phiên bản khác nhau của ứng dụng (ví dụ: bạn có thể thực hiện việc này với Clickonce). Có thể cho các phiên bản khác nhau của ứng dụng để lưu các cài đặt khác nhau.

(2) Khi bạn nâng cấp một ứng dụng, lớp cài đặt có thể đã bị thay đổi và có thể không tương thích với những gì đã lưu, điều này có thể dẫn đến sự cố.

Tuy nhiên, chúng tôi đã giúp dễ dàng nâng cấp cài đặt từ phiên bản trước của ứng dụng lên phiên bản mới nhất. Chỉ cần gọi ApplicationSettingsBase.Upgrade () và nó sẽ truy xuất các cài đặt từ phiên bản trước phù hợp với phiên bản hiện tại của lớp và lưu trữ chúng trong tệp user.config của phiên bản hiện tại. Bạn cũng có tùy chọn ghi đè hành vi này trong lớp cài đặt hoặc trong triển khai trình cung cấp của bạn.

H: Được rồi, nhưng làm cách nào để biết khi nào gọi Nâng cấp?

A: Câu hỏi hay. Trong Clickonce, khi bạn cài đặt phiên bản mới của ứng dụng, ApplicationSettingsBase sẽ phát hiện phiên bản đó và tự động nâng cấp cài đặt cho bạn tại thời điểm cài đặt được tải. Trong các trường hợp không phải Clickonce, không có nâng cấp tự động - bạn phải tự gọi Nâng cấp. Dưới đây là một ý tưởng để xác định thời điểm gọi Nâng cấp:

Có một cài đặt boolean được gọi là CallUpgrade và cung cấp cho nó một giá trị mặc định là true. Khi ứng dụng của bạn khởi động, bạn có thể làm những việc như:

if (Properties.Settings.Value.CallUpgrade)
{
   Properties.Settings.Value.Upgrade();
   Properties.Settings.Value.CallUpgrade = false;    
}

Điều này sẽ đảm bảo rằng Nâng cấp () chỉ được gọi trong lần đầu tiên ứng dụng chạy sau khi một phiên bản mới được triển khai.

Tôi không tin trong một giây rằng nó thực sự có thể hoạt động - không có cách nào mà Microsoft cung cấp khả năng này, nhưng phương pháp vẫn giống nhau.


3
TỔNG CÔNG VIỆC NÀY! Tôi chỉ sử dụng if(CallUpgrade) { Upgrade(); }câu lệnh đơn giản .
Anthony Mastrean

@Ian Boyd: Tôi thích ý tưởng này và tôi hoàn toàn hứng thú về việc có một giải pháp tiềm năng, tuy nhiên tôi bối rối về một điều. Tôi không có Properties.Settings.Value Tôi có Properties.Settingsmột phần nhưng tôi thiếu một cái gì đó hoặc đó là cụ thể cho bạn?
Paladin khúc xạ

8
Điều này hoạt động tốt, nhưng tôi nhắc người đọc rằng đường dẫn của cấu hình lên đến trừ số phiên bản phải giống nhau. tức là xem câu trả lời của @ Amr. Ví dụ: nếu một phiên bản mới của ứng dụng được khởi chạy từ một đường dẫn tệp khác với phiên bản trước đó, thì phiên bản Upgradenày không hoạt động.
Stephen Swensen

1
@RefractedPaladin nóProperties.Settings.Default.Upgrade()
Stephen Swensen

5
Đừng quên thêm Properties.Settings.Default.Save();sau khi thay đổi nó thành false :-)
Jeff

32

Tệp user.config được lưu trữ tại

c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<verison>

<c:\Documents and Settings>là thư mục dữ liệu người dùng, không chuyển vùng (Cài đặt cục bộ ở trên) hoặc chuyển vùng.
<username>là tên người dùng.
<companyname>là giá trị CompanyNameAttribute, nếu có. Nếu không, hãy bỏ qua yếu tố này.
<appdomainname>là AppDomain.CurrentDomain.FriendlyName. Điều này thường mặc định là tên .exe.
<eid>là URL, StrongName hoặc Đường dẫn, dựa trên bằng chứng có sẵn để băm.
<hash>là bằng chứng băm SHA1 được thu thập từ CurrentDomain, theo thứ tự ưu tiên sau:
1. StrongName
2. URL:
Nếu cả hai đều không có sẵn, hãy sử dụng đường dẫn .exe.
<version>là cài đặt AssemblyVersionAttribute của AssemblyInfo.

Mô tả đầy đủ ở đây http://msdn.microsoft.com/en-us/library/ms379611.aspx


4

(Tôi muốn thêm điều này làm bình luận cho câu trả lời của @ Amr, nhưng tôi chưa có đủ đại diện để làm điều đó.)

Các thông tin trong bài viết MSDN là rất rõ ràng và dường như vẫn áp dụng. Tuy nhiên, nó không đề cập đến rằng hàm băm SHA1 được viết ra mã hóa cơ sở 32, thay vì cơ sở 16 điển hình hơn.

Tôi tin rằng thuật toán đang được sử dụng được triển khai ToBase32StringSuitableForDirName, có thể tìm thấy ở đây trong Nguồn tham khảo của Microsoft .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.