Bagaimana saya bisa menyimpan pengaturan aplikasi dalam aplikasi Windows Forms?

582

Apa yang ingin saya capai sangat sederhana: Saya memiliki aplikasi Windows Forms (.NET 3.5) yang menggunakan jalur untuk membaca informasi. Jalur ini dapat dimodifikasi oleh pengguna, dengan menggunakan formulir opsi yang saya berikan.

Sekarang, saya ingin menyimpan nilai jalur ke file untuk digunakan nanti. Ini akan menjadi salah satu dari banyak pengaturan yang disimpan ke file ini. File ini akan duduk langsung di folder aplikasi.

Saya mengerti ada tiga opsi yang tersedia:

  • File ConfigurationSettings (appname.exe.config)
  • Daftar
  • File XML khusus

Saya membaca bahwa file konfigurasi .NET tidak diramalkan untuk menyimpan nilai kembali ke sana. Adapun registri, saya ingin mendapatkan sejauh mungkin darinya.

Apakah ini berarti saya harus menggunakan file XML khusus untuk menyimpan pengaturan konfigurasi?

Jika demikian, saya ingin melihat contoh kode dari itu (C #).

Saya telah melihat diskusi lain tentang hal ini, tetapi masih belum jelas bagi saya.

Berbahan bakar
sumber
Apakah ini aplikasi .NET WinForms? Jika demikian, versi .NET apa yang Anda kembangkan?
Portman
1
Ya, ini adalah aplikasi .NET framework versi 3.5 WinForms.
Dipicu
1
Anda perlu menyimpan kata sandi atau nilai rahasia ? Mungkin memerlukan enkripsi
Kiquenet

Jawaban:

593

Jika Anda bekerja dengan Visual Studio maka cukup mudah untuk mendapatkan pengaturan yang tetap. Klik kanan pada proyek di Solution Explorer dan pilih Properties. Pilih tab Pengaturan dan klik hyperlink jika pengaturan tidak ada.

Gunakan tab Pengaturan untuk membuat pengaturan aplikasi. Visual Studio membuat file Settings.settingsdan Settings.Designer.settingsyang berisi kelas tunggal yang Settingsdiwarisi dari ApplicationSettingsBase . Anda dapat mengakses kelas ini dari kode Anda untuk membaca / menulis pengaturan aplikasi:

Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file

Teknik ini berlaku untuk konsol, Formulir Windows, dan jenis proyek lainnya.

Perhatikan bahwa Anda perlu mengatur properti lingkup pengaturan Anda. Jika Anda memilih Ruang lingkup aplikasi maka Pengaturan. Kesalahan. <Properti Anda> akan menjadi hanya-baca.

Referensi: Cara: Menulis Pengaturan Pengguna saat Jalankan dengan C # - Microsoft Documents

aku
sumber
2
jika saya punya solusi, apakah ini berlaku untuk seluruh solusi atau untuk setiap proyek?
franko_camron
8
@ Empat: Saya punya proyek .NET 4.0 WinApp di sini, dan SomeProperty saya tidak hanya bisa dibaca. Settings.Default.SomeProperty = 'value'; Settings.Default.Save();bekerja seperti pesona. Atau apakah itu karena saya punya pengaturan Pengguna?
doekman
4
@ Empat: Ketika saya mengubah pengaturan dari Pengguna ke lingkup Aplikasi dan menyimpan file, saya melihat dalam kode yang dihasilkan setter menghilang. Ini juga terjadi dengan profil Klien 4.0 ...
doekman
3
@ Empat: tautan bagus, meskipun pernyataan Anda bahwa Settings.Default.Save()tidak ada yang salah. Seperti yang dinyatakan oleh @aku dalam jawaban, pengaturan ruang lingkup aplikasi hanya-baca: save tidak efektif untuk mereka. Gunakan PortableSettingsProvider tersuai untuk menyimpan pengaturan lingkup pengguna ke app.config yang berlokasi di mana exe bukan yang ada di folder AppData pengguna. Tidak, umumnya tidak baik, tapi saya menggunakannya selama pengembangan untuk menggunakan pengaturan yang sama dari kompilasi ke kompilasi (tanpa itu, mereka pergi folder pengguna unik baru dengan setiap kompilasi).
ikan kecil
7
Sampai sekarang, dengan .NET 3.5 tampaknya Anda hanya dapat menggunakan Settings.Default.SomeProperty untuk menetapkan nilai dan mendapatkan typecasting yang kuat. Juga, untuk menghemat waktu orang lain (perlu beberapa saat untuk mencari tahu), Anda harus mengetik Properties.Settings.Default, atau menambahkan menggunakan YourProjectNameSpace.Settings ke bagian atas file Anda. "Pengaturan" saja tidak didefinisikan / ditemukan.
eselk
95

Jika Anda berencana menyimpan ke file dalam direktori yang sama dengan yang dapat dieksekusi, berikut ini adalah solusi bagus yang menggunakan format JSON :

using System;
using System.IO;
using System.Web.Script.Serialization;

namespace MiscConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            MySettings settings = MySettings.Load();
            Console.WriteLine("Current value of 'myInteger': " + settings.myInteger);
            Console.WriteLine("Incrementing 'myInteger'...");
            settings.myInteger++;
            Console.WriteLine("Saving settings...");
            settings.Save();
            Console.WriteLine("Done.");
            Console.ReadKey();
        }

        class MySettings : AppSettings<MySettings>
        {
            public string myString = "Hello World";
            public int myInteger = 1;
        }
    }

    public class AppSettings<T> where T : new()
    {
        private const string DEFAULT_FILENAME = "settings.json";

        public void Save(string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(this));
        }

        public static void Save(T pSettings, string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(pSettings));
        }

        public static T Load(string fileName = DEFAULT_FILENAME)
        {
            T t = new T();
            if(File.Exists(fileName))
                t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
            return t;
        }
    }
}
Trevor
sumber
Ya, ubah DEFAULT_FILENAME ke jalur absolut jika Anda ingin menyimpan ke direktori lain. Saya pikir itu paling umum untuk menyimpan file ke direktori yang sama dengan aplikasi, atau sub-direktori, jika Anda tidak menyimpannya ke registri.
Trevor
Oh, mungkin opsi yang lebih baik adalah menyimpan file pengaturan di folder appdata pengguna.
Trevor
1
Tidak perlu berubah DEFAULT_FILENAME, panggil saja settings.Save(theFileToSaveTo); Menjadi semua topi, DEFAULT_FILENAMEseharusnya konstan . Jika Anda ingin properti baca-tulis, buat satu dan minta konstruktor untuk mengaturnya DEFAULT_FILENAME. Kemudian miliki nilai argumen default null, uji untuk ini dan gunakan properti Anda sebagai nilai default. Ini sedikit lebih mengetik, tetapi memberi Anda antarmuka yang lebih standar.
Jesse Chisholm
10
Anda perlu referensi System.Web.Extensions.dlljika Anda belum melakukannya.
TEK
9
Saya telah membuat seluruh perpustakaan berdasarkan jawaban ini dengan banyak perbaikan dan membuatnya tersedia di nuget: github.com/Nucs/JsonSettings
NucS
67

Registri tidak dapat digunakan. Anda tidak yakin apakah pengguna yang menggunakan aplikasi Anda, memiliki hak yang cukup untuk menulis ke registri.

Anda dapat menggunakan app.configfile untuk menyimpan pengaturan level aplikasi (yang sama untuk setiap pengguna yang menggunakan aplikasi Anda).

Saya akan menyimpan pengaturan khusus pengguna dalam file XML, yang akan disimpan di Penyimpanan Terpencil atau di direktori SpecialFolder.ApplicationData .

Di samping itu, mulai dari. NET 2.0, dimungkinkan untuk menyimpan nilai kembali ke app.configfile.

Frederik Gheysels
sumber
8
Namun, gunakan registri, jika Anda ingin pengaturan per-login / pengguna.
thenonhacker
19
Registri tidak dapat portble
Kb.
10
@thenonhacker: Atau gunakan Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)
Kenny Mann
4
Registri pengguna dapat ditulis (banyak program menulis informasi di sana, dan izin pengguna tidak pernah menjadi masalah). Keuntungan menggunakan registri dibandingkan menggunakan pengaturan adalah bahwa jika Anda memiliki beberapa aplikasi yang berbagi folder yang sama, (katakanlah, program pengaturan dan program aplikasi), mereka tidak akan berbagi pengaturan yang sama.
Kesty
3
Kerugian utama dari Registry adalah cara sulit untuk mengekspor / menyalin pengaturan ke PC lain. Tetapi saya tidak setuju dengan "Anda tidak yakin apakah pengguna yang menggunakan aplikasi Anda, memiliki hak yang cukup untuk menulis ke registri" - Di HKEY_CURRENT_USER Anda selalu memiliki hak untuk menulis. Ini dapat ditolak tetapi sistem file juga tidak dapat diakses oleh pengguna saat ini (semua folder TEMP yang memungkinkan, dll).
i486
20

The ApplicationSettingskelas tidak mendukung menyimpan pengaturan ke app.config berkas. Itu sangat banyak dengan desain; aplikasi yang berjalan dengan akun pengguna yang diamankan dengan benar (pikirkan Vista UAC) tidak memiliki akses tulis ke folder instalasi program.

Anda dapat melawan sistem dengan ConfigurationManagerkelas. Tetapi solusi sepele adalah pergi ke desainer Pengaturan dan mengubah ruang lingkup pengaturan untuk Pengguna. Jika itu menyebabkan kesulitan (katakanlah, pengaturan itu relevan untuk setiap pengguna), Anda harus meletakkan fitur Opsi Anda dalam program terpisah sehingga Anda dapat meminta prompt elevasi privilege. Atau lepaskan menggunakan pengaturan.

Hans Passant
sumber
Bisakah Anda memperluas kalimat terakhir Anda? Minta elevasi untuk menulis app.config atau untuk menulis aplikasi terpisah yang akan melalui semua pengguna di rumah, cari pengguna.config dan edit ini?
CannibalSmith
2
Program terpisah membutuhkan manifes untuk meminta ketinggian. Google 'sebagai invoker memerlukan administrator' untuk menemukan sintaksis yang tepat. Mengedit user.config tidak praktis, juga tidak perlu.
Hans Passant
18

Argumen registry / configurationSettings / XML masih tampak sangat aktif. Saya telah menggunakan semuanya, karena teknologinya telah berkembang, tetapi favorit saya didasarkan pada sistem Threed yang dikombinasikan dengan Isolated Storage .

Sampel berikut memungkinkan penyimpanan objek bernama properti ke file dalam penyimpanan terisolasi. Seperti:

AppSettings.Save(myobject, "Prop1,Prop2", "myFile.jsn");

Properti dapat dipulihkan menggunakan:

AppSettings.Load(myobject, "myFile.jsn");

Ini hanya sampel, tidak menyarankan praktik terbaik.

internal static class AppSettings
{
    internal static void Save(object src, string targ, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = src.GetType();

        string[] paramList = targ.Split(new char[] { ',' });
        foreach (string paramName in paramList)
            items.Add(paramName, type.GetProperty(paramName.Trim()).GetValue(src, null));

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify.
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write((new JavaScriptSerializer()).Serialize(items));
            }

        }
        catch (Exception) { }   // If fails - just don't use preferences
    }

    internal static void Load(object tar, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = tar.GetType();

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
            using (StreamReader reader = new StreamReader(stream))
            {
                items = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(reader.ReadToEnd());
            }
        }
        catch (Exception) { return; }   // If fails - just don't use preferences.

        foreach (KeyValuePair<string, object> obj in items)
        {
            try
            {
                tar.GetType().GetProperty(obj.Key).SetValue(tar, obj.Value, null);
            }
            catch (Exception) { }
        }
    }
}
Boczek
sumber
1
Atau lebih baik lagi; gunakan DataContractJsonSerializer
Boczek
16

Saya ingin berbagi perpustakaan yang saya bangun untuk ini. Ini adalah perpustakaan kecil, tetapi peningkatan besar (IMHO) lebih dari file pengaturan.

Perpustakaan disebut Jot (GitHub) . Ini adalah artikel Proyek Kode lama yang saya tulis tentangnya.

Begini cara Anda menggunakannya untuk melacak ukuran dan lokasi jendela:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

Keuntungan dibandingkan dengan file .settings: Ada kode yang jauh lebih sedikit, dan itu jauh lebih sedikit kesalahan karena Anda hanya perlu menyebutkan setiap properti sekali .

Dengan file pengaturan Anda perlu menyebutkan setiap properti lima kali: sekali ketika Anda secara eksplisit membuat properti dan tambahan empat kali dalam kode yang menyalin nilai bolak-balik.

Penyimpanan, serialisasi, dll. Sepenuhnya dapat dikonfigurasi. Ketika objek target dibuat oleh wadah IoC , Anda dapat [menghubungkannya] [] sehingga berlaku pelacakan secara otomatis ke semua objek yang diputuskannya, sehingga semua yang perlu Anda lakukan untuk membuat properti persisten adalah menampar [dilacak] atribut di atasnya.

Ini sangat dapat dikonfigurasi, dan Anda dapat mengkonfigurasi: - ketika data tetap ada dan diterapkan secara global atau untuk setiap objek yang dilacak - bagaimana serialisasi - di mana itu disimpan (misalnya file, database, online, penyimpanan terisolasi, registri) - aturan yang dapat membatalkan penerapan / data yang ada untuk properti

Percayalah, perpustakaan adalah kedudukan tertinggi!

anakic
sumber
14

Cara sederhana adalah dengan menggunakan objek data konfigurasi, simpan sebagai file XML dengan nama aplikasi di Folder lokal dan saat startup membacanya kembali.

Berikut adalah contoh untuk menyimpan posisi dan ukuran formulir.

Objek data konfigurasi sangat diketik dan mudah digunakan:

[Serializable()]
public class CConfigDO
{
    private System.Drawing.Point m_oStartPos;
    private System.Drawing.Size m_oStartSize;

    public System.Drawing.Point StartPos
    {
        get { return m_oStartPos; }
        set { m_oStartPos = value; }
    }

    public System.Drawing.Size StartSize
    {
        get { return m_oStartSize; }
        set { m_oStartSize = value; }
    }
}

Kelas manajer untuk menyimpan dan memuat:

public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configuration file
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configuration file
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}

Sekarang Anda bisa membuat sebuah instance dan menggunakan di form memuat dan menutup acara:

    private CConfigMng oConfigMng = new CConfigMng();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load configuration
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save configuration
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }

Dan file XML yang dihasilkan juga dapat dibaca:

<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>
Dieter Meemken
sumber
1
Saya memiliki ini bekerja sangat baik dalam pengembangan, tetapi ketika saya menyebarkan aplikasi rata-rata pengguna tidak memiliki akses ke c:\program files\my applicationfolder, sehingga penghematan pengaturan membuat kesalahan. Saya ingin menyimpan file xml di AppData, tetapi saya hanya ingin tahu apakah ada cara yang jelas untuk mengatasi masalah ini, karena pendekatan ini tampaknya berhasil untuk Anda.
Philip Stratford
@ PhilipStratford Karena ini hanya file biasa, Anda dapat menyimpannya di mana saja. Temukan saja tempat dengan akses tulis.
Dieter Meemken
@ PhilipStratford Mungkin folder AppData adalah opsi untuk Anda, lihat C # mendapatkan path dari% AppData% , sebagaimana disebutkan oleh layang-layang .
Dieter Meemken
Terima kasih, saya sudah menerapkan ini, menyimpan file xml di folder AppDate. Saya hanya bertanya-tanya apakah ada cara mudah untuk menyimpannya di folder aplikasi sesuai contoh Anda, karena saya berasumsi Anda telah membuatnya berfungsi. Jangan khawatir, folder AppData mungkin adalah lokasi yang lebih baik!
Philip Stratford
5

Opsi lain, alih-alih menggunakan file XML khusus, kita dapat menggunakan format file yang lebih ramah pengguna: file JSON atau YAML.

  • Jika Anda menggunakan .NET 4.0 dinamis, pustaka ini sangat mudah digunakan (bersambung, deserialize, objek bersarang, mendukung dan memesan output sesuai keinginan + menggabungkan beberapa pengaturan menjadi satu) JsonConfig (penggunaan setara dengan ApplicationSettingsBase)
  • Untuk .NET YAML configuration library ... Saya belum menemukan yang semudah digunakan seperti JsonConfig

Anda dapat menyimpan file pengaturan Anda di beberapa folder khusus (untuk semua pengguna dan per pengguna) seperti yang tercantum di sini Environment.SpecialFolder Enumeration dan beberapa file (hanya baca default, per peran, per pengguna, dll.)

Jika Anda memilih untuk menggunakan beberapa pengaturan, Anda dapat menggabungkan pengaturan itu: Misalnya, menggabungkan pengaturan untuk default + BasicUser + AdminUser. Anda dapat menggunakan aturan Anda sendiri: yang terakhir menimpa nilainya, dll.

layang-layang
sumber
4

"Apakah ini berarti saya harus menggunakan file XML khusus untuk menyimpan pengaturan konfigurasi?" Tidak, belum tentu. Kami menggunakan SharpConfig untuk operasi semacam itu.

Misalnya, jika file konfigurasi seperti itu

[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment

Kami dapat mengambil nilai seperti ini

var config = Configuration.LoadFromFile("sample.cfg");
var section = config["General"];

string someString = section["SomeString"].StringValue;
int someInteger = section["SomeInteger"].IntValue;

Ini kompatibel dengan .NET 2.0 dan lebih tinggi. Kami dapat membuat file konfigurasi dengan cepat dan kami dapat menyimpannya nanti.

Sumber: http://sharpconfig.net/
GitHub: https://github.com/cemdervis/SharpConfig

Turker Tunali
sumber
3

Sejauh yang saya tahu, .NET mendukung pengaturan tetap menggunakan fasilitas pengaturan aplikasi bawaan:

Fitur Pengaturan Aplikasi Formulir Windows memudahkan untuk membuat, menyimpan, dan memelihara aplikasi kustom dan preferensi pengguna di komputer klien. Dengan pengaturan aplikasi Windows Forms, Anda tidak hanya dapat menyimpan data aplikasi seperti string koneksi database, tetapi juga data spesifik pengguna, seperti preferensi aplikasi pengguna. Menggunakan Visual Studio atau kode yang dikelola khusus, Anda dapat membuat pengaturan baru, membacanya dari dan menulisnya ke disk, mengikatnya ke properti di formulir Anda, dan memvalidasi data pengaturan sebelum memuat dan menyimpan. - http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx

Yakub
sumber
2
Tidak benar .. lihat jawaban aku di atas. itu mungkin menggunakan Pengaturan dan ApplicationSettingsBase
Gishu
2

Kadang-kadang Anda ingin menyingkirkan pengaturan yang disimpan dalam file web.config atau app.config tradisional. Anda ingin kontrol berbutir halus atas penyebaran entri pengaturan Anda dan desain data yang terpisah. Atau persyaratannya adalah mengaktifkan penambahan entri baru saat runtime.

Saya bisa membayangkan dua pilihan bagus:

  • Versi yang sangat diketik dan
  • Versi berorientasi objek.

Keuntungan dari versi yang diketik sangat adalah nama pengaturan dan nilai yang diketik sangat. Tidak ada risiko mencampur nama atau tipe data. Kerugiannya adalah bahwa lebih banyak pengaturan harus dikodekan, tidak dapat ditambahkan saat runtime.

Dengan versi berorientasi objek keuntungannya adalah bahwa pengaturan baru dapat ditambahkan saat runtime. Tetapi Anda tidak memiliki nama dan nilai yang sangat diketik. Harus berhati-hati dengan pengidentifikasi string. Harus tahu tipe data yang disimpan sebelumnya ketika mendapatkan nilai.

Anda dapat menemukan kode dari kedua implementasi yang berfungsi penuh di SINI .

pengguna3130351
sumber
2

Ya, adalah mungkin untuk menyimpan konfigurasi - tetapi itu sangat tergantung pada cara Anda memilih untuk melakukannya. Biarkan saya menjelaskan perbedaan teknis sehingga Anda dapat memahami opsi yang Anda miliki:

Pertama, Anda perlu membedakan, apakah Anda ingin menggunakan applicationSettings atau AppSettings dalam file Anda *.exe.config(alias App.configdalam Visual Studio) - ada perbedaan mendasar, dijelaskan di sini .

Keduanya menyediakan berbagai cara untuk menyimpan perubahan:

  • The AppSettings memungkinkan Anda untuk membaca dan menulis langsung ke file konfigurasi (melalui config.Save(ConfigurationSaveMode.Modified);, di mana konfigurasi didefinisikan sebagai config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);).

  • Pengaturan Application memungkinkan untuk membaca, tetapi jika Anda menulis perubahan (melalui Properties.Settings.Default.Save();) itu akan ditulis pada basis per-pengguna, disimpan di tempat khusus (misalnya C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0). Seperti yang disebutkan Hans Passant dalam jawabannya, ini karena pengguna biasanya memiliki hak terbatas untuk File Program dan tidak dapat menulis ke sana tanpa memohon prompt UAC. Kerugiannya adalah jika Anda menambahkan kunci konfigurasi di masa depan, Anda perlu menyinkronkannya dengan setiap profil pengguna.

Catatan: Seperti yang disebutkan dalam pertanyaan, ada opsi ke - 3: Jika Anda memperlakukan file konfigurasi sebagai dokumen XML, Anda dapat memuat, memodifikasi, dan menyimpannya dengan menggunakan System.Xml.Linq.XDocumentkelas. Tidak perlu menggunakan file XML khusus, Anda dapat membaca file konfigurasi yang ada; untuk elemen kueri, Anda bahkan dapat menggunakan kueri Linq. Saya telah memberikan contoh di sini , periksa fungsi GetApplicationSettingdi sana dalam jawabannya.

Jika Anda memerlukan enkripsi untuk melindungi nilai-nilai Anda, periksa jawaban ini .

Mat
sumber
Terima kasih atas jawaban yang luar biasa ini.
NoChance
2
@NoChance - Sama-sama, senang saya bisa membantu Anda!
Matt
Bagus! Akhirnya menemukan semuanya 😂😂😂
Momoro
1
@ Mamo - senang mendengar! ;-)
Matt
1
public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}
Paul - Soura Tech LLC
sumber