मैं एक विंडोज फॉर्म एप्लीकेशन में एप्लिकेशन सेटिंग्स कैसे बचा सकता हूं?


581

मैं जो हासिल करना चाहता हूं वह बहुत सरल है: मेरे पास एक विंडोज फॉर्म (.NET 3.5) एप्लिकेशन है जो जानकारी पढ़ने के लिए एक पथ का उपयोग करता है। इस पथ को उपयोगकर्ता द्वारा संशोधित किया जा सकता है, मेरे द्वारा प्रदान किए गए विकल्प फॉर्म का उपयोग करके।

अब, मैं बाद में उपयोग के लिए फ़ाइल के लिए पथ मान सहेजना चाहता हूं। यह इस फ़ाइल में सहेजी गई कई सेटिंग्स में से एक होगा। यह फ़ाइल सीधे एप्लिकेशन फ़ोल्डर में बैठती है।

मैं समझता हूं कि तीन विकल्प उपलब्ध हैं:

  • विन्यास फाइल (appname.exe.config)
  • रजिस्ट्री
  • कस्टम XML फ़ाइल

मैंने पढ़ा कि .NET कॉन्फ़िगरेशन फ़ाइल वापस मानों को सहेजने के लिए अग्रणी नहीं है। रजिस्ट्री के लिए, मैं जितना हो सके इससे दूर जाना चाहूंगा।

क्या इसका मतलब यह है कि मुझे कॉन्फ़िगरेशन सेटिंग्स को बचाने के लिए एक कस्टम XML फ़ाइल का उपयोग करना चाहिए?

यदि हां, तो मैं उस (C #) का कोड उदाहरण देखना चाहूंगा।

मैंने इस विषय पर अन्य चर्चाएँ देखी हैं, लेकिन यह अभी भी मेरे लिए स्पष्ट नहीं है।


यह एक .NET WinForms अनुप्रयोग है? यदि हां, तो .NET का कौन सा संस्करण विकसित कर रहे हैं?
पोर्टमैन

1
हाँ, यह एक .NET फ्रेमवर्क संस्करण 3.5 WinForms अनुप्रयोग है।
ईंधन

1
क्या आपको पासवर्ड या गोपनीयता मूल्यों को सहेजने की आवश्यकता है ? शायद किसी भी एन्क्रिप्शन की
Kiquenet

जवाबों:


593

यदि आप विजुअल स्टूडियो के साथ काम करते हैं तो लगातार सेटिंग प्राप्त करना बहुत आसान है। समाधान एक्सप्लोरर में परियोजना पर राइट क्लिक करें और गुण चुनें। सेटिंग्स टैब चुनें और अगर सेटिंग्स मौजूद नहीं है तो हाइपरलिंक पर क्लिक करें।

एप्लिकेशन सेटिंग बनाने के लिए सेटिंग टैब का उपयोग करें। Visual Studio फ़ाइलों को बनाता है Settings.settingsऔर Settings.Designer.settingsजिसमें ApplicationSettingsBaseSettings से विरासत में मिली सिंगलटन क्लास होती है । आप एप्लिकेशन सेटिंग पढ़ने / लिखने के लिए अपने कोड से इस वर्ग तक पहुंच सकते हैं:

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

यह तकनीक कंसोल, विंडोज फॉर्म और अन्य प्रोजेक्ट प्रकारों के लिए लागू है।

ध्यान दें कि आपको अपनी सेटिंग्स की गुंजाइश संपत्ति निर्धारित करने की आवश्यकता है । यदि आप एप्लिकेशन स्कोप चुनते हैं तो Settings.Default। <अपनी संपत्ति> केवल-पढ़ने के लिए होगी।

संदर्भ: कैसे करें: सी # - माइक्रोसॉफ्ट डॉक्स के साथ रन टाइम पर उपयोगकर्ता सेटिंग्स लिखें


2
अगर मेरे पास कोई समाधान है, तो क्या यह संपूर्ण समाधान के लिए या प्रत्येक परियोजना के लिए लागू होगा?
franko_camron

8
@ आपका नाम: मुझे यहां एक .NET 4.0 WinApp प्रोजेक्ट मिला है, और मेरी SomeProperty आसानी से नहीं है। Settings.Default.SomeProperty = 'value'; Settings.Default.Save();एक जादू की तरह काम करता है। या ऐसा इसलिए है क्योंकि मुझे उपयोगकर्ता-सेटिंग्स मिल गई हैं?
डॉकमैन

4
@ आपका नाम: जब मैंने उपयोगकर्ता से एप्लिकेशन-स्कोप में एक सेटिंग को बदला और फ़ाइल को सहेजा, तो मैंने उत्पन्न कोड में देखा कि सेटर गायब हो गया है। यह क्लाइंट प्रोफाइल 4.0 के साथ भी होता है ...
डॉकमैन

3
@Four: बढ़िया लिंक, हालांकि आपका कथन कि Settings.Default.Save()कुछ भी गलत नहीं है। जैसा कि उत्तर में @aku कहता है, ऐप-स्कोप सेटिंग केवल-पढ़ने के लिए हैं: उनके लिए सेव अप्रभावी है। ऐप -config जहां उपयोगकर्ता उपयोगकर्ता के AppData फ़ोल्डर में एक के बजाय स्थित है, उपयोगकर्ता-स्कोप सेटिंग्स को सहेजने के लिए उस कस्टम PortableSettingsProvider का उपयोग करें । नहीं, आम तौर पर अच्छा नहीं है, लेकिन मैं इसे संकलन से संकलन (डब्ल्यू / ओ) के लिए समान सेटिंग्स का उपयोग करने के लिए विकास के दौरान उपयोग करता हूं, वे प्रत्येक संकलन के साथ नए अद्वितीय उपयोगकर्ता फ़ोल्डर जाते हैं)।
नाबालिग

7
.NET 3.5 के साथ, ऐसा प्रतीत होता है कि आप केवल Settings.Default.SomeProperty का उपयोग कर सकते हैं एक मूल्य असाइन करें और मजबूत टाइपकास्टिंग प्राप्त करें। इसके अलावा, दूसरों का समय बचाने के लिए (मुझे यह पता लगाने में थोड़ा समय लगा), आपको या तो Properties.Settings.Default टाइप करने की जरूरत है, या अपनी फाइल के शीर्ष पर YourProjectNameSpace.Settings का उपयोग करना है। अकेले "सेटिंग" परिभाषित / नहीं है।
21

94

यदि आप अपने निष्पादन योग्य समान निर्देशिका के भीतर एक फ़ाइल को सहेजने की योजना बना रहे हैं, तो यहां एक अच्छा समाधान है जो 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;
        }
    }
}

यदि आप किसी अन्य निर्देशिका को सहेजना चाहते हैं, तो DEFAULT_FILENAME को पूर्ण पथ में बदलें। मुझे लगता है कि फ़ाइल को एप्लिकेशन या उप-निर्देशिका के समान निर्देशिका में सहेजना सबसे आम है, यदि आप उन्हें रजिस्ट्री में नहीं सहेज रहे हैं।
ट्रेवर

ओह, शायद बेहतर विकल्प उपयोगकर्ता के ऐपडेटा फ़ोल्डर में सेटिंग्स फ़ाइल को संग्रहीत करना होगा।
ट्रेवर

1
बदलने की जरूरत नहीं DEFAULT_FILENAME, सिर्फ पुकार settings.Save(theFileToSaveTo); सभी कैप होने के नाते, DEFAULT_FILENAMEयह एक स्थिर माना जाता है । यदि आप पठन-पाठन संपत्ति चाहते हैं, तो एक बनाएं और निर्माणकर्ता के पास निर्धारित करें DEFAULT_FILENAME। फिर डिफ़ॉल्ट तर्क मान हो null, इसके लिए परीक्षण करें और अपनी संपत्ति को डिफ़ॉल्ट मान के रूप में उपयोग करें। यह थोड़ा अधिक टाइपिंग है, लेकिन आपको अधिक मानक इंटरफ़ेस देता है।
जेसी चिशोल्म

10
System.Web.Extensions.dllयदि आपको पहले से नहीं है तो आपको संदर्भ देना होगा।
TEK

9
मैंने कई सुधारों के साथ इस उत्तर के आधार पर एक पूरी लाइब्रेरी बनाई है और इसे nuget में उपलब्ध कराया है: github.com/Nucs/JsonSettings
NucS

67

रजिस्ट्री एक नो-गो है। आप सुनिश्चित नहीं हैं कि जो उपयोगकर्ता आपके एप्लिकेशन का उपयोग करता है, उसके पास रजिस्ट्री में लिखने के लिए पर्याप्त अधिकार हैं।

आप app.configएप्लिकेशन-स्तर सेटिंग्स को बचाने के लिए फ़ाइल का उपयोग कर सकते हैं (जो आपके एप्लिकेशन का उपयोग करने वाले प्रत्येक उपयोगकर्ता के लिए समान हैं)।

मैं एक XML फ़ाइल में उपयोगकर्ता-विशिष्ट सेटिंग्स संग्रहीत करूंगा, जो कि पृथक संग्रहण या SpecialFolder.ApplicationData निर्देशिका में सहेजा जाएगा ।

उसके बाद, .NET 2.0 से, मानों को app.configफ़ाइल में वापस संग्रहीत करना संभव है ।


8
यदि आप प्रति-लॉगिन / उपयोगकर्ता सेटिंग्स चाहते हैं, तो रजिस्ट्री का उपयोग करें।
तत्कालीन प्रहरी

19
रजिस्ट्री गैर-पोर्टबल है
Kb।

10
@thenonhacker: या Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData) का उपयोग करें
केनी मान

4
उपयोगकर्ता रजिस्ट्री को लिखा जा सकता है (बहुत सारे कार्यक्रम वहां जानकारी लिखते हैं, और उपयोगकर्ता अनुमतियाँ कभी भी समस्या नहीं होती हैं)। सेटिंग्स का उपयोग करके रजिस्ट्री का उपयोग करने का लाभ यह है कि यदि आपके पास एक ही फ़ोल्डर साझा करने वाले कई एप्लिकेशन हैं, (कहते हैं, सेटअप प्रोग्राम और एप्लिकेशन प्रोग्राम), तो वे समान सेटिंग्स साझा नहीं करेंगे।
Kesty

3
रजिस्ट्री का मुख्य नुकसान अन्य पीसी पर सेटिंग्स को निर्यात / कॉपी करने का कठिन तरीका है। लेकिन मैं इस बात से सहमत नहीं हूं कि "आप यह सुनिश्चित नहीं कर सकते हैं कि जो उपयोगकर्ता आपके एप्लिकेशन का उपयोग करता है, उसके पास रजिस्ट्री में लिखने के लिए पर्याप्त अधिकार हैं" - HKEY_CURRENT_USER में आपको हमेशा लिखने का अधिकार है। इसे अस्वीकार किया जा सकता है लेकिन वर्तमान उपयोगकर्ता (सभी संभावित TEMP फ़ोल्डर, आदि) के लिए फाइल सिस्टम भी अप्राप्य हो सकता है।
--६

20

ApplicationSettingsवर्ग के लिए सेटिंग्स को बचाने का समर्थन नहीं करता app.config फ़ाइल। यह डिजाइन द्वारा बहुत अधिक है; एप्लिकेशन जो ठीक से सुरक्षित उपयोगकर्ता खाते के साथ चलते हैं (सोचते हैं कि विस्टा यूएसी) प्रोग्राम के इंस्टॉलेशन फ़ोल्डर तक पहुंच नहीं है।

आप ConfigurationManagerक्लास के साथ सिस्टम से लड़ सकते हैं । लेकिन तुच्छ वर्कअराउंड सेटिंग्स डिजाइनर में जाना और उपयोगकर्ता के लिए सेटिंग का दायरा बदलना है। यदि यह कठिनाई का कारण बनता है (कहते हैं, सेटिंग प्रत्येक उपयोगकर्ता के लिए प्रासंगिक है), तो आपको अपना विकल्प सुविधा एक अलग कार्यक्रम में रखना चाहिए ताकि आप विशेषाधिकार उन्नयन के लिए कह सकें। या एक सेटिंग का उपयोग करके फोरगो।


क्या आप अपने अंतिम वाक्य पर विस्तार कर सकते हैं? App.config लिखने के लिए या एक अलग एप्लिकेशन लिखने के लिए, जो सभी उपयोगकर्ताओं के होम फ़ोलरों के माध्यम से जाना जाएगा, user.config की तलाश करें और इन्हें संपादित करें?
CannibalSmith

2
अलग-अलग कार्यक्रम में उन्नयन के लिए पूछने के लिए एक उपस्थिति की आवश्यकता होती है। उचित सिंटैक्स खोजने के लिए Google 'asinvoker requireadministrator'। User.config का संपादन व्यावहारिक नहीं है, और न ही आवश्यक है।
हंस पासेंट

18

रजिस्ट्री / कॉन्फ़िगरेशनसेटिंग्स / XML तर्क अभी भी बहुत सक्रिय लगता है। मैंने उन सभी का उपयोग किया है, जैसा कि तकनीक ने प्रगति की है, लेकिन मेरा पसंदीदा आइसोलेटेड स्टोरेज के साथ थ्रस्ट सिस्टम पर आधारित है ।

निम्नलिखित नमूना अलग-अलग भंडारण में एक फ़ाइल नाम की वस्तुओं के भंडारण की अनुमति देता है। जैसे कि:

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

गुण का उपयोग करके पुनर्प्राप्त किया जा सकता है:

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

यह सिर्फ एक नमूना है, सर्वोत्तम प्रथाओं का विचारोत्तेजक नहीं।

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

1
या अभी भी बेहतर है; DataContractJsonSerializer का उपयोग करें
Boczek

16

मैं एक पुस्तकालय साझा करना चाहता था जिसे मैंने इसके लिए बनाया है। यह एक छोटी सी लाइब्रेरी है, लेकिन एक बड़ी सुधार (IMHO) ओवरसेटिंग फाइलें।

पुस्तकालय को जोत (गिटहब) कहा जाता है । यहाँ एक पुराना द कोड प्रोजेक्ट लेख है जिसके बारे में मैंने लिखा था।

यहां बताया गया है कि आप इसका उपयोग किसी विंडो के आकार और स्थान का ट्रैक रखने के लिए कैसे करेंगे:

public MainWindow()
{
    InitializeComponent();

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

.Settings फ़ाइलों की तुलना में लाभ: काफी कम कोड है, और यह बहुत कम त्रुटि-प्रवण है क्योंकि आपको केवल एक बार प्रत्येक संपत्ति का उल्लेख करने की आवश्यकता है ।

सेटिंग्स फ़ाइलों के साथ आपको प्रत्येक संपत्ति का पांच बार उल्लेख करने की आवश्यकता होती है : एक बार जब आप स्पष्ट रूप से संपत्ति बनाते हैं और कोड में चार बार अतिरिक्त होते हैं जो मूल्यों को आगे और पीछे कॉपी करते हैं।

भंडारण, क्रमांकन आदि पूरी तरह से विन्यास योग्य हैं। जब लक्ष्य वस्तुएं एक IoC कंटेनर द्वारा बनाई जाती हैं , तो आप इसे [हुक कर सकते हैं] [] ताकि यह उन सभी वस्तुओं के लिए स्वचालित रूप से ट्रैकिंग पर लागू हो जाए जो इसे हल करती हैं, ताकि आपको संपत्ति के लगातार बने रहने के लिए सभी करने की आवश्यकता हो [एक ट्रैक करने योग्य] उस पर विशेषता।

यह अत्यधिक कॉन्फ़िगर करने योग्य है, और आप कॉन्फ़िगर कर सकते हैं: - जब डेटा को बनाए रखा जाता है और वैश्विक रूप से या प्रत्येक ट्रैक की गई वस्तु के लिए लागू किया जाता है - यह कैसे क्रमबद्ध होता है - जहां इसे संग्रहीत किया जाता है (जैसे फ़ाइल, डेटाबेस, ऑनलाइन, अलग-अलग भंडारण, रजिस्ट्री) - नियम जो लागू करना रद्द कर सकते हैं / किसी प्रॉपर्टी के लिए स्थायी डेटा

मेरा विश्वास करो, पुस्तकालय शीर्ष पायदान है!


14

एक सरल तरीका कॉन्फ़िगरेशन डेटा ऑब्जेक्ट का उपयोग करना है, इसे स्थानीय फ़ोल्डर में एप्लिकेशन के नाम के साथ XML फ़ाइल के रूप में सहेजें और स्टार्टअप पर इसे वापस पढ़ें।

यहां एक फॉर्म की स्थिति और आकार को संग्रहीत करने के लिए एक उदाहरण है।

कॉन्फ़िगरेशन डेटाबजेक्ट दृढ़ता से टाइप किया गया है और उपयोग करने में आसान है:

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

बचत और लोड करने के लिए एक प्रबंधक वर्ग:

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

अब आप एक उदाहरण बना सकते हैं और अपने फॉर्म के लोड और करीबी घटनाओं में उपयोग कर सकते हैं:

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

और उत्पादित XML फ़ाइल भी पठनीय है:

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

1
मेरे पास विकास में यह बहुत अच्छा है, लेकिन जब मैं एप्लिकेशन को तैनात करता हूं तो औसत उपयोगकर्ता के पास c:\program files\my applicationफ़ोल्डर तक पहुंच नहीं होती है , इसलिए सेटिंग्स को सहेजना एक त्रुटि फेंकता है। मैं इसके बजाय AppData में xml फ़ाइल को सहेजने में देख रहा हूं, लेकिन मुझे आश्चर्य है कि अगर इस समस्या का कोई स्पष्ट तरीका है, क्योंकि यह दृष्टिकोण आपके लिए काम कर रहा है।
फिलिप स्ट्रैटफ़ोर्ड

@PhilipStratford चूंकि यह केवल एक सामान्य फ़ाइल है, आप इसे कहीं भी सहेज सकते हैं। बस लिखने की पहुंच के साथ एक जगह ढूंढें।
डाइटर मीमकेन

@PhilipStratford हो सकता है कि AppData फ़ोल्डर आपके लिए एक विकल्प हो, C # को% AppData% का पथ मिल रहा है , जैसा कि पतंग द्वारा बताया गया है ।
डाइटर मीमकेन

धन्यवाद, मैंने पहले ही इसे लागू कर दिया है, AppDate फ़ोल्डर में xml फ़ाइल को सहेज रहा है। मुझे बस आश्चर्य हुआ कि क्या आपके उदाहरण के अनुसार, एप्लिकेशन के फ़ोल्डर में इसे सहेजने का एक आसान तरीका था, क्योंकि मैंने मान लिया था कि आपने इसे काम किया था। चिंता की बात नहीं है, AppData फ़ोल्डर वैसे भी एक बेहतर स्थान है!
फिलिप स्ट्रैटफ़ोर्ड


5

अन्य विकल्प, कस्टम XML फ़ाइल का उपयोग करने के बजाय, हम अधिक उपयोगकर्ता के अनुकूल फ़ाइल प्रारूप का उपयोग कर सकते हैं: JSON या YAML फ़ाइल।

  • यदि आप .NET 4.0 डायनेमिक का उपयोग करते हैं, तो यह लाइब्रेरी वास्तव में उपयोग करना आसान है (सीरियलाइज़, डीसर्लाइज़, नेस्टेड ऑब्जेक्ट्स सपोर्ट और ऑर्डरिंग आउटपुट, जैसा कि आप चाहते हैं + एक से अधिक सेटिंग्स मर्ज करें) JsonConfig (उपयोग ApplicationSettingsbase के बराबर है)
  • .NET YAML कॉन्फ़िगरेशन लाइब्रेरी के लिए ... मुझे JsonConfig के रूप में उपयोग करना आसान नहीं है

आप अपनी सेटिंग्स फ़ाइल को कई विशेष फ़ोल्डरों में (सभी उपयोगकर्ताओं और प्रति उपयोगकर्ता के लिए) स्टोर कर सकते हैं जैसा कि यहां सूचीबद्ध है। पर्यावरणविशेष फोल्डर गणना और कई फाइलें (डिफ़ॉल्ट रूप से केवल पढ़ने के लिए, प्रति उपयोगकर्ता, आदि)

यदि आप कई सेटिंग्स का उपयोग करना चुनते हैं, तो आप उन सेटिंग्स को मर्ज कर सकते हैं: उदाहरण के लिए, डिफ़ॉल्ट + BasicUser + AdminUser के लिए सेटिंग्स मर्ज करना। आप अपने स्वयं के नियमों का उपयोग कर सकते हैं: अंतिम एक मूल्य से अधिक हो जाता है, आदि।


4

"क्या इसका मतलब यह है कि मुझे कॉन्फ़िगरेशन सेटिंग्स को बचाने के लिए एक कस्टम XML फ़ाइल का उपयोग करना चाहिए?" नहीं, जरूरी नहीं। हम ऐसे ऑपरेशंस के लिए SharpConfig का इस्तेमाल करते हैं।

उदाहरण के लिए, यदि एक कॉन्फ़िगरेशन फ़ाइल ऐसा है

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

हम इस तरह से मूल्यों को पुनः प्राप्त कर सकते हैं

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

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

यह .NET 2.0 और उच्चतर के साथ संगत है। हम मक्खी पर कॉन्फ़िगरेशन फ़ाइलें बना सकते हैं और हम इसे बाद में सहेज सकते हैं।

स्रोत: http://sharpconfig.net/
GitHub: https://github.com/cemdervis/SharpCubfig


3

जहाँ तक मैं बता सकता हूँ, .NET अंतर्निहित एप्लिकेशन सेटिंग सुविधा का उपयोग करके स्थायी सेटिंग्स का समर्थन करता है:

विंडोज फॉर्म की एप्लिकेशन सेटिंग्स सुविधा क्लाइंट कंप्यूटर पर कस्टम एप्लिकेशन और उपयोगकर्ता वरीयताओं को बनाने, संग्रहीत करने और बनाए रखने में आसान बनाती है। Windows प्रपत्र एप्लिकेशन सेटिंग्स के साथ, आप न केवल एप्लिकेशन डेटा जैसे डेटाबेस कनेक्शन स्ट्रिंग्स, बल्कि उपयोगकर्ता-विशिष्ट डेटा, जैसे कि अन्य एप्लिकेशन प्राथमिकताएँ संग्रहीत कर सकते हैं। विजुअल स्टूडियो या कस्टम प्रबंधित कोड का उपयोग करके, आप नई सेटिंग्स बना सकते हैं, उन्हें पढ़ सकते हैं और उन्हें डिस्क पर लिख सकते हैं, उन्हें आपके प्रपत्रों पर गुणों से बाँध सकते हैं, और लोड करने और सहेजने से पहले सेटिंग्स डेटा को मान्य कर सकते हैं। - http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx


2
सच नहीं .. ऊपर अकु का जवाब देखिए। सेटिंग्स और ApplicationSettingsBase का उपयोग करना संभव है
Gishu

2

कभी-कभी आप पारंपरिक web.config या app.config फ़ाइल में रखी गई सेटिंग्स से छुटकारा पाना चाहते हैं। आप अपनी सेटिंग्स प्रविष्टियों और अलग किए गए डेटा डिज़ाइन की तैनाती पर अधिक महीन दानेदार नियंत्रण चाहते हैं। या आवश्यकता रनटाइम पर नई प्रविष्टियों को जोड़ने में सक्षम है।

मैं दो अच्छे विकल्पों की कल्पना कर सकता हूं:

  • दृढ़ता से टाइप किया गया संस्करण और
  • ऑब्जेक्ट ओरिएंटेड संस्करण।

दृढ़ता से टाइप किए गए संस्करण का लाभ दृढ़ता से टाइप की गई सेटिंग्स के नाम और मूल्य हैं। नाम या डेटा प्रकारों को आपस में जोड़ने का कोई जोखिम नहीं है। नुकसान यह है कि अधिक सेटिंग्स को कोडित करना होगा, रनटाइम में जोड़ा नहीं जा सकता है।

ऑब्जेक्ट ओरिएंटेड संस्करण के साथ लाभ यह है कि रनटाइम में नई सेटिंग्स जोड़ी जा सकती हैं। लेकिन आपके पास दृढ़ता से टाइप किए गए नाम और मूल्य नहीं हैं। स्ट्रिंग पहचानकर्ताओं से सावधान रहना चाहिए। मान प्राप्त करते समय पहले सहेजे गए डेटा प्रकार को जानना चाहिए।

आप यहां पूरी तरह कार्यात्मक कार्यान्वयन के कोड पा सकते हैं ।


2

हां, कॉन्फ़िगरेशन को सहेजना संभव है - लेकिन यह बहुत कुछ इस बात पर निर्भर करता है कि आप इसे करने के लिए क्या चुनते हैं। मुझे तकनीकी अंतरों का वर्णन करने दें ताकि आप उन विकल्पों को समझ सकें जो आपके पास हैं:

सबसे पहले, आपको भेद करने की आवश्यकता है, चाहे आप अपनी (उर्फ इन विजुअल स्टूडियो) फ़ाइल में एप्लिकेशनसेटिंग या ऐपसेटिंग का उपयोग करना चाहते हों - यहां मूलभूत अंतर हैं, जिनका वर्णन किया जा रहा है*.exe.configApp.config

दोनों परिवर्तन सहेजने के विभिन्न तरीके प्रदान करते हैं:

  • AppSettings आप पढ़ सकते हैं और कॉन्फ़िग फ़ाइल में सीधे लिखने (के माध्यम से करने की अनुमति config.Save(ConfigurationSaveMode.Modified);है, जहां config के रूप में परिभाषित किया गया है config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);)।

  • ApplicationSettings को पढ़ने के लिए अनुमति देते हैं, लेकिन यदि आप परिवर्तन (के माध्यम से लिखने Properties.Settings.Default.Save();) यह एक प्रति उपयोगकर्ता के आधार पर लिखा जाएगा एक विशेष स्थान (जैसे में संग्रहित C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0)। जैसा कि हंस पसंत ने अपने उत्तर में उल्लेख किया है, ऐसा इसलिए है क्योंकि एक उपयोगकर्ता के पास आमतौर पर प्रोग्राम फाइल्स के अधिकार हैं और यूएसी प्रॉम्प्ट को आमंत्रित किए बिना इसे नहीं लिख सकते हैं। एक नुकसान यह है कि यदि आप भविष्य में कॉन्फ़िगरेशन कुंजियों को जोड़ रहे हैं, तो आपको उन्हें हर उपयोगकर्ता प्रोफ़ाइल के साथ सिंक्रनाइज़ करने की आवश्यकता है।

नोट: जैसा कि प्रश्न में उल्लेख किया गया है, एक 3 विकल्प है: यदि आप कॉन्फ़िगरेशन फ़ाइल को XML दस्तावेज़ के रूप में मानते हैं , तो आप System.Xml.Linq.XDocumentकक्षा का उपयोग करके इसे लोड, संशोधित और सहेज सकते हैं । कस्टम XML फ़ाइल का उपयोग करने की आवश्यकता नहीं है, आप मौजूदा कॉन्फ़िगर फ़ाइल को पढ़ सकते हैं; तत्वों को क्वेरी करने के लिए, आप Linq प्रश्नों का भी उपयोग कर सकते हैं। मैंने यहां एक उदाहरण दिया है , GetApplicationSettingउत्तर में फ़ंक्शन की जांच करें ।

यदि आपको अपने मूल्यों की सुरक्षा के लिए एन्क्रिप्शन की आवश्यकता है , तो इस उत्तर को देखें।


इस उत्कृष्ट उत्तर के लिए धन्यवाद।
NoChance

2
@ नोचैन्स - आपका स्वागत है, खुशी है कि मैं आपकी मदद कर सका!
मैट

अच्छा! अंत में यह सब पता लगा
oro

1
@Momoro - सुनने के लिए अच्छा है! ;-)
मैट

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();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.