2008-08-25 34 views
52

Tôi có ứng dụng .NET 2.0 Windows Forms. Vị trí tốt nhất của cài đặt người dùng cửa hàng (xem nguyên tắc Windows) ở đâu?Cách tốt nhất để lưu cài đặt người dùng cho ứng dụng .NET là gì?

Một số người chỉ đến Application.LocalUserAppDataPath. Tuy nhiên, tạo ra một cấu trúc thư mục như:

C: \ Documents and Settings \ user_name \ Local Settings \ Application Data \ COMPANY_NAME \ PRODUCT_NAME \ PRODUCT_VERSION \

Nếu tôi phát hành phiên bản 1 của tôi ứng dụng và lưu trữ một tệp XML ở đó, sau đó phát hành phiên bản 2, có thể thay đổi thành một thư mục khác, đúng không? Tôi muốn có một thư mục, mỗi người dùng, để lưu trữ các cài đặt, bất kể phiên bản ứng dụng.

+0

Tôi nghĩ rằng [bài viết này] (http://blog.kowalczyk.info/kb/getting-user-specific-application-data-directory-for-.net-winforms-apps.html) đề cập đến giải pháp. –

+0

[Cập nhật liên kết] (https://blog.kowalczyk.info/article/10b/Getting-user-specific-application-data-directory.html) từ bình luận của Jorges. – tm1

Trả lời

74

Tôi thích sử dụng tích hợp sẵn Application Settings. Sau đó, bạn đã xây dựng trong hỗ trợ cho việc sử dụng các nhà thiết kế thiết lập nếu bạn muốn hiển thị ở thời gian thiết kế, hoặc trong thời gian chạy để sử dụng:

// read setting 
string setting1 = (string)Settings.Default["MySetting1"]; 
// save setting 
Settings.Default["MySetting2"] = "My Setting Value"; 

// you can force a save with 
Properties.Settings.Default.Save(); 

Nó lưu trữ các thiết lập trong một cấu trúc thư mục tương tự như bạn mô tả (với các phiên bản trong con đường). Tuy nhiên, với một cuộc gọi đơn giản để:

Properties.Settings.Default.Upgrade(); 

Ứng dụng sẽ kéo tất cả các thiết lập các phiên bản trước để tiết kiệm trong

+1

Cảm ơn bạn đã nâng cấp() mẹo. –

+3

điều gây phiền nhiễu duy nhất về 'Settings.Default' là bạn cần phải tạo chúng bằng tay trước, không giống' NSUserDefaults' trong Cocoa trả về nil nếu cài đặt không tồn tại. – Ali

+3

Không gian tên nào ở đây? Tôi dường như không có quyền truy cập vào một đối tượng Settings trong của tôi.NET 4 ứng dụng winforms. – NickG

1

Cài đặt là cặp khóa-giá trị chuẩn (chuỗi chuỗi). Tôi có thể bọc chúng trong một tập tin XML, nếu điều đó giúp.

Tôi muốn sử dụng hệ thống tệp thay vì sổ đăng ký. Nó có vẻ là dễ dàng hơn để duy trì. Trong các tình huống hỗ trợ, nếu người dùng cần mở/thay đổi cài đặt theo cách thủ công, điều đó sẽ dễ dàng hơn nếu nó nằm trong hệ thống tệp.

0

Tôi sẽ đi xuống danh sách thư mục bạn đã đăng ngoại trừ phiên bản sản phẩm. Bạn không muốn đặt lại cài đặt sau khi bản cập nhật được phát hành.

Tôi thực sự đang chuyển khỏi sổ đăng ký cho cài đặt người dùng do yếu tố gỡ lỗi/dấu chân. Tôi hiện chỉ lưu trữ một vài cài đặt cơ bản (kích thước cửa sổ, vị trí, phiên bản của tệp dữ liệu) trong sổ đăng ký và tôi đã gặp phải nhiều sự cố hơn nếu bản cập nhật xấu hoặc người dùng mất màn hình thứ hai và đó là nơi ứng dụng đang mở. Một vài người trong số họ đủ hiểu biết về regedit, nhưng đối với phần còn lại họ phải cài đặt lại, nhanh chóng, nhưng tôi nghĩ họ càu nhàu một chút. Với phiên bản dựa trên tệp, tất cả những gì tôi phải làm là mở chúng ra một tệp XML trong Notepad và thực hiện một tinh chỉnh nhanh.

Ngoài ra, tôi đang tìm cách làm cho ứng dụng của mình có thể chạy khỏi ổ flash USB và việc cài đặt được gắn vào tệp có vẻ thân thiện hơn với quy trình đó. Tôi chắc chắn tôi có thể làm một số mã để kiểm tra/làm sạch registry, nhưng tôi nghĩ rằng hầu hết chúng ta đã mệt mỏi của sự lộn xộn registry mà dường như ăn lên máy của chúng ta ngày nay.

Tôi biết có một số sự cân bằng bảo mật cho điều này, nhưng không có dữ liệu nào tôi sắp xếp là quan trọng đối với nguyên nhân đó và tôi không bị bất kỳ lần truy cập hiệu suất nào do kích thước của ứng dụng.

2

Một cách tiếp cận đó đã làm việc cho tôi trong quá khứ đã được để tạo ra một lớp các thiết lập và. sử dụng tuần tự hóa XML để ghi nó vào hệ thống tệp. Bạn có thể mở rộng khái niệm này bằng cách tạo một tập hợp các đối tượng cài đặt và tuần tự hóa nó.Bạn sẽ có tất cả các cài đặt của mình cho tất cả người dùng ở một nơi mà không phải lo lắng về việc quản lý hệ thống tệp.

Trước khi bất cứ ai cho tôi bất kỳ flak để phát minh lại một phần bánh xe, hãy để tôi nói một vài điều. Đối với một, nó chỉ là một vài dòng mã để serialize và ghi các tập tin. Thứ hai, nếu bạn có một đối tượng chứa cài đặt của mình, bạn không phải thực hiện nhiều cuộc gọi đến đối tượng appSettings khi bạn tải ứng dụng của mình. Và cuối cùng, rất dễ dàng để thêm các mục đại diện cho trạng thái ứng dụng của bạn, do đó cho phép bạn tiếp tục một tác vụ dài khi ứng dụng tải tiếp theo.

+0

Nếu bạn sẵn sàng xây dựng tuần tự hóa XML tùy chỉnh, tại sao không tuần tự hóa nó thành một cài đặt ứng dụng đơn lẻ? Bằng cách đó bạn có thể sử dụng cơ sở hạ tầng cài đặt ứng dụng. Tạo một trình chuyển đổi loại hoặc lớp serializable và sau đó nhập lớp bằng cách sử dụng hộp thoại cài đặt ứng dụng. –

4

Hoặc viết cài đặt của bạn trong tệp xml và lưu bằng cách sử dụng Isolated Storage. Tùy thuộc vào cửa hàng bạn sử dụng nó lưu nó trong thư mục Application Data. Bạn cũng có thể chọn một cửa hàng được kích hoạt chuyển vùng có nghĩa là khi người dùng đăng nhập vào một máy tính khác, các cài đặt sẽ di chuyển với họ.

0

Bộ nhớ riêng được sử dụng chủ yếu cho các ứng dụng được phân phối sử dụng ClickOnce và được chạy trong một hộp cát an toàn. Con đường cơ sở được quyết định cho bạn và bạn sẽ không thể suy ra nó trong mã của bạn. Đường dẫn sẽ giống như "\ LocalSettings \ ApplicationData \ IsolatedStorage \ ejwnwe.302 \ kfiwemqi.owx \ url.asdaiojwejoieajae ....", không phải tất cả đều thân thiện. Dung lượng lưu trữ của bạn cũng bị giới hạn.

Ryan Farley has it right.

7

Các ứng dụng .NET có cơ chế cài đặt sẵn có dễ sử dụng. Vấn đề với nó, theo ý kiến ​​của tôi, là nó lưu trữ các thiết lập đó vào một thư mục khá mơ hồ và người dùng cuối sẽ không thể tìm thấy nó. Hơn nữa, chỉ cần chuyển từ gỡ lỗi sang bản phát hành thay đổi vị trí của thư mục này, có nghĩa là mọi cài đặt được lưu trong một cấu hình đều bị mất ở cấu hình khác.

Vì những lý do này và lý do khác, tôi đã đưa ra my own settings code for Windows Forms. Nó không phải là khá trơn tru như là một trong đó đi kèm với NET, nhưng nó linh hoạt hơn, và tôi sử dụng nó tất cả các thời gian.

1

tôi thử một số phương pháp để lưu trữ các thiết lập của tôi chỉ đơn giản là tập tin văn bản và tôi tìm thấy cách tốt nhất:

tập tin được lưu trữ trong thư mục ứng dụng, đến việc sử dụng, Settings.txt: (bên trong các thiết lập tập tin đã được phê duyệt bình luận, hãy thử // bình luận)

// để có được thiết lập giá trị

Settings.Get("name", "Ivan"); 

// để đặt thiết lập giá trị

Settings.Set("name", "John"); 

sử dụng:

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Windows.Forms; 

// bạn có thể lưu trữ cũng với tên phần, sử dụng chỉ cần thêm phần tên Set (SECTION_NAME, tên, giá trị) và Nhận (SECTION_NAME, tên, giá trị)

public static class Settings 
{ 
    private static string SECTION = typeof(Settings).Namespace;//"SETTINGS"; 
    private static string settingsPath = Application.StartupPath.ToString() + "\\settings.txt"; 
    [DllImport("kernel32")] 
    private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 
    [DllImport("kernel32")] 
    private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); 
    public static String GetString(String name) 
    { 
     StringBuilder temp = new StringBuilder(255); 
     int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath); 
     return temp.ToString(); 
    } 
    public static String Get(String name, String defVal) 
    { 
     return Get(SECTION,name,defVal); 
    } 
    public static String Get(string _SECTION, String name, String defVal) 
    { 
     StringBuilder temp = new StringBuilder(255); 
     int i = GetPrivateProfileString(_SECTION, name, "", temp, 255, settingsPath); 
     return temp.ToString(); 
    } 
    public static Boolean Get(String name, Boolean defVal) 
    { 
     return Get(SECTION, name, defVal); 
    } 
    public static Boolean Get(string _SECTION, String name, Boolean defVal) 
    { 
     StringBuilder temp = new StringBuilder(255); 
     int i = GetPrivateProfileString(_SECTION,name,"",temp,255,settingsPath); 
     bool retval=false; 
     if (bool.TryParse(temp.ToString(),out retval)) 
     { 
      return retval; 
     } else 
     { 
      return retval; 
     } 
    } 
    public static int Get(String name, int defVal) 
    { 
     return Get(SECTION, name, defVal); 
    } 
    public static int Get(string _SECTION, String name, int defVal) 
    { 
     StringBuilder temp = new StringBuilder(255); 
     int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath); 
     int retval=0; 
     if (int.TryParse(temp.ToString(),out retval)) 
     { 
      return retval; 
     } else 
     { 
      return retval; 
     } 
    } 
    public static void Set(String name, String val) 
    { 
     Set(SECTION, name,val); 
    } 
    public static void Set(string _SECTION, String name, String val) 
    { 
     WritePrivateProfileString(_SECTION, name, val, settingsPath); 
    } 
    public static void Set(String name, Boolean val) 
    { 
     Set(SECTION, name, val); 
    } 
    public static void Set(string _SECTION, String name, Boolean val) 
    { 
     WritePrivateProfileString(_SECTION, name, val.ToString(), settingsPath); 
    } 
    public static void Set(String name, int val) 
    { 
     Set(SECTION, name, val); 
    } 
    public static void Set(string _SECTION,String name, int val) 
    { 
     WritePrivateProfileString(SECTION, name, val.ToString(), settingsPath); 
    } 
} 
Các vấn đề liên quan