Windows Forms 응용 프로그램에서 응용 프로그램 설정을 저장하려면 어떻게해야합니까?


582

달성하고자하는 것은 매우 간단합니다. 정보를 읽는 경로를 사용하는 Windows Forms (.NET 3.5) 응용 프로그램이 있습니다. 이 경로는 내가 제공 한 옵션 양식을 사용하여 사용자가 수정할 수 있습니다.

이제 나중에 사용할 수 있도록 경로 값을 파일에 저장하려고합니다. 이것은이 파일에 저장된 많은 설정 중 하나입니다. 이 파일은 응용 프로그램 폴더에 직접 저장됩니다.

세 가지 옵션을 사용할 수 있음을 이해합니다.

  • ConfigurationSettings 파일 (appname.exe.config)
  • 기재
  • 사용자 정의 XML 파일

.NET 구성 파일이 값을 다시 저장할 것으로 예상되지 않는다는 것을 읽었습니다. 레지스트리에 관해서는 가능한 한 멀리 떨어지고 싶습니다.

이것은 사용자 정의 XML 파일을 사용하여 구성 설정을 저장해야 함을 의미합니까?

그렇다면 해당 코드 예제 (C #)를보고 싶습니다.

이 주제에 대한 다른 토론을 보았지만 여전히 명확하지 않습니다.


.NET WinForms 응용 프로그램입니까? 그렇다면 어떤 .NET 버전을 개발하고 있습니까?
포트만

1
예. .NET Framework 버전 3.5 WinForms 응용 프로그램입니다.
09:15에 연료를 공급

1
비밀번호 나 비밀 값을 저장해야 합니까? 어쩌면 암호화
Kiquenet

답변:


593

Visual Studio로 작업하면 지속 가능한 설정을 얻는 것이 매우 쉽습니다. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택하십시오. 설정이 존재하지 않으면 설정 탭을 선택하고 하이퍼 링크를 클릭하십시오.

설정 탭을 사용하여 응용 프로그램 설정을 만듭니다. Visual Studio에서 파일을 생성 Settings.settings하고 Settings.Designer.settings그 싱글 톤 클래스를 포함 Settings로부터 상속 ApplicationSettingsBase을 . 코드에서이 클래스에 액세스하여 응용 프로그램 설정을 읽고 쓸 수 있습니다.

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

이 기술은 콘솔, Windows Forms 및 기타 프로젝트 유형 모두에 적용 할 수 있습니다.

설정의 범위 속성 을 설정해야합니다 . 응용 프로그램 범위를 선택하면 설정. 기본. <사용자 속성>이 읽기 전용이됩니다.

참조 : 방법 : C #을 사용하여 런타임시 사용자 설정 작성 -Microsoft Docs


2
솔루션이있는 경우 전체 솔루션 또는 각 프로젝트에 적용됩니까?
franko_camron

8
@ Four : 여기에 .NET 4.0 WinApp 프로젝트가 있으며 SomeProperty는 읽기 전용이 아닙니다. Settings.Default.SomeProperty = 'value'; Settings.Default.Save();매력처럼 작동합니다. 아니면 사용자 설정이 있기 때문입니까?
doekman

4
@ Four : 설정을 User에서 Application-scope로 변경하고 파일을 저장하면 생성 된 코드에서 setter가 사라지는 것을 보았습니다. 이것은 또한 클라이언트 프로파일 4.0에서도 발생합니다 ...
doekman

3
@Four : 훌륭한 링크이지만, Settings.Default.Save()아무것도하지 않는다는 진술 은 정확하지 않습니다. 답변에 @aku가 언급했듯이 앱 범위 설정은 읽기 전용입니다. 저장은 효과적이지 않습니다. 해당 사용자 정의 PortableSettingsProvider 를 사용하여 사용자 범위 설정을 exe가 사용자의 AppData 폴더에있는 것이 아닌 app.config에 저장하십시오. 아니요, 일반적으로 좋지는 않지만 개발 중에 컴파일에서 컴파일에 동일한 설정을 사용하기 위해 사용합니다 (그것은 각 컴파일마다 새로운 고유 사용자 폴더로 이동합니다).
minnow

7
현재 .NET 3.5에서는 Settings.Default.SomeProperty를 사용하여 값을 할당하고 강력한 유형 캐스팅을 얻을 수 있습니다. 또한 다른 사람들의 시간을 절약하려면 (이를 알아내는 데 시간이 걸렸습니다) Properties.Settings.Default를 입력하거나 YourProjectNameSpace.Settings를 사용하여 파일 맨 위에 추가해야합니다. "설정"만 정의 / 발견되지 않았습니다.
eselk

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을 절대 경로로 변경하십시오. 파일을 레지스트리에 저장하지 않으면 응용 프로그램과 동일한 디렉토리 또는 하위 디렉토리에 파일을 저장하는 것이 가장 일반적이라고 생각합니다.
Trevor

아마도 더 나은 옵션은 설정 파일을 사용자의 appdata 폴더에 저장하는 것입니다.
Trevor

1
변화에 대한 필요가 DEFAULT_FILENAME, 단지 호출하지 settings.Save(theFileToSaveTo); 모든 한도 DEFAULT_FILENAME일정 해야합니다 . 읽기 / 쓰기 속성을 원하면 속성을 만들고 생성자로 설정하십시오 DEFAULT_FILENAME. 그런 다음 기본 인수 값을로 설정 null하고이를 테스트하고 속성을 기본값으로 사용하십시오. 조금 더 타이핑하지만 더 표준적인 인터페이스를 제공합니다.
Jesse Chisholm

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
로그인 / 사용자 별 설정을 원할 경우 레지스트리를 사용하십시오.
thenonhacker

19
레지스트리가 이식 불가능합니다
Kb.

10
@thenonhacker : 또는 사용 Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)
케니 맨

4
사용자 레지스트리를 쓸 수 있습니다 (많은 프로그램이 정보를 작성하므로 사용자 권한은 문제가되지 않습니다). 설정을 사용하는 것보다 레지스트리를 사용하는 것의 장점은 동일한 폴더를 공유하는 여러 응용 프로그램 (예 : 설치 프로그램 및 응용 프로그램)이 동일한 설정을 공유하지 않는다는 것입니다.
Kesty

3
레지스트리의 주요 단점은 설정을 다른 PC로 내보내거나 복사하는 어려운 방법입니다. 그러나 "응용 프로그램을 사용하는 사용자에게 레지스트리에 쓸 수있는 충분한 권한이 있는지 확실하지 않습니다"라는 것에 동의하지 않습니다.-HKEY_CURRENT_USER에는 항상 쓸 수있는 권한이 있습니다. 거부 될 수 있지만 현재 사용자 (모든 가능한 TEMP 폴더 등)가 파일 시스템에 액세스 할 수 없습니다.
i486

20

ApplicationSettings클래스에 설정을 저장을 지원하지 않습니다 의 app.config 파일. 그것은 의도적으로 설계된 것입니다. 올바르게 보안 된 사용자 계정으로 실행되는 응용 프로그램 (Vista UAC 생각)은 프로그램의 설치 폴더에 대한 쓰기 권한이 없습니다.

당신은 ConfigurationManager클래스 와 시스템을 싸울 수 있습니다 . 그러나 간단한 해결 방법은 설정 디자이너로 이동하여 설정 범위를 사용자로 변경하는 것입니다. 이로 인해 어려움이 발생하는 경우 (즉, 설정은 모든 사용자와 관련이 있습니다) 옵션 기능을 별도의 프로그램에 넣어서 권한 상승 프롬프트를 요청할 수 있습니다. 또는 설정을 사용하여 포기하십시오.


마지막 문장을 넓히시겠습니까? app.config를 작성하거나 모든 사용자의 홈 폴더를 통과 할 별도의 응용 프로그램을 작성하도록 권한 상승을 요청하고 user.config를 찾아서 편집 하시겠습니까?
CannibalSmith

2
별도의 프로그램에는 상승을 요구하는 매니페스트가 필요합니다. 적절한 구문을 찾으려면 Google 'asinvoker requireadministrator'입니다. user.config 편집은 실용적이 아니며 필요하지 않습니다.
Hans Passant

18

registry / configurationSettings / XML 인수는 여전히 매우 활성화 된 것으로 보입니다. 기술이 발전함에 따라 나는 그것들을 모두 사용했지만, 내가 가장 좋아하는 것은 Isolated Storage 와 결합 된 Threed의 시스템을 기반으로합니다. 합니다.

다음 샘플에서는 properties라는 객체를 격리 된 저장소의 파일에 저장할 수 있습니다. 같은 :

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

내가 만든 라이브러리를 공유하고 싶었습니다. 작은 라이브러리이지만 .settings 파일보다 큰 개선 (IMHO)입니다.

라이브러리를 Jot (GitHub) 라고 합니다. 여기에 내가 쓴 코드 프로젝트 기사 가 있습니다.

창의 크기와 위치를 추적하는 데 사용하는 방법은 다음과 같습니다.

public MainWindow()
{
    InitializeComponent();

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

.settings 파일과 비교할 때의 이점 : 코드가 상당히 적으며 각 속성을 한 번만 언급하면되므로 오류가 훨씬 적습니다 .

설정 파일을 사용하면 각 속성을 5 번 언급해야합니다. 속성 을 명시 적으로 만들 때 한 번, 코드에서 값을 앞뒤로 복사하는 추가 4 번 을 언급해야 합니다.

스토리지, 직렬화 등을 완전히 구성 할 수 있습니다. 대상 객체가 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 파일을 저장하려고하지만이 방법이 효과가있는 것처럼 보이기 때문에이 문제를 해결할 수있는 방법이 있는지 궁금합니다.
Philip Stratford

@PhilipStratford 일반 파일이므로 어디에서나 저장할 수 있습니다. 쓰기 권한이있는 장소를 찾으십시오.
Dieter Meemken

@PhilipStratford AppData 폴더가 옵션 일 수 있습니다 . kite에서 언급 한 것처럼 C #에서 % AppData %의 경로를 얻는 방법을 참조하십시오 .
Dieter Meemken

고마워, 나는 이미 이것을 구현하여 AppDate 폴더에 xml 파일을 저장했다. 방금 예제로 응용 프로그램의 폴더에 저장하는 쉬운 방법이 있는지 궁금했습니다. 걱정하지 마십시오. AppData 폴더는 아마도 더 좋은 위치 일 것입니다!
Philip Stratford


5

사용자 지정 XML 파일을 사용하는 대신 다른 옵션 인 JSON 또는 YAML 파일과 같은보다 사용자 친화적 인 파일 형식을 사용할 수 있습니다.

  • .NET 4.0 동적을 사용하는 경우이 라이브러리는 사용하기가 매우 쉽습니다 (직렬화, 역 직렬화, 중첩 된 오브젝트 지원 및 원하는대로 출력을 순서화 + 여러 설정을 하나로 병합) JsonConfig (사용은 ApplicationSettingsBase와 동일)
  • .NET YAML 구성 라이브러리의 경우 ... JsonConfig만큼 사용하기 쉬운 것을 찾지 못했습니다.

Environment.SpecialFolder 열거 및 여러 파일 (기본 읽기 전용, 역할 별, 사용자 별 등)에 나열된대로 모든 사용자 및 사용자 별 여러 특수 폴더에 설정 파일을 저장할 수 있습니다 .

여러 설정을 사용하도록 선택한 경우 해당 설정을 병합 할 수 있습니다 (예 : 기본 + 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/SharpConfig


3

내가 알 수있는 한 .NET은 내장 응용 프로그램 설정 기능을 사용하여 지속 설정을 지원합니다.

Windows Forms의 응용 프로그램 설정 기능을 사용하면 클라이언트 컴퓨터에서 사용자 지정 응용 프로그램 및 사용자 기본 설정을 쉽게 작성, 저장 및 유지 관리 할 수 ​​있습니다. Windows Forms 응용 프로그램 설정을 사용하면 데이터베이스 연결 문자열과 같은 응용 프로그램 데이터뿐만 아니라 사용자 응용 프로그램 기본 설정과 같은 사용자 별 데이터도 저장할 수 있습니다. Visual Studio 또는 사용자 지정 관리 코드를 사용하면 새 설정을 만들고, 디스크에서 읽고 디스크에 쓰고, 양식의 속성에 바인딩하고,로드 및 저장하기 전에 설정 데이터의 유효성을 검사 할 수 있습니다. -http : //msdn.microsoft.com/en-us/library/k4s6c3a0.aspx


2
사실이 아닙니다. 위의 aku의 답변을 참조하십시오. 설정 및 ApplicationSettingsBase를 사용하여 가능
Gishu

2

때로는 전통적인 web.config 또는 app.config 파일에 저장된 설정을 제거하고 싶을 수도 있습니다. 설정 항목의 배포 및 별도의 데이터 디자인을보다 세밀하게 제어하려고합니다. 또는 런타임에 새 항목을 추가 할 수 있어야합니다.

두 가지 좋은 옵션을 상상할 수 있습니다.

  • 강력한 형식의 버전
  • 객체 지향 버전.

강력한 형식의 버전의 장점은 강력한 형식의 설정 이름과 값입니다. 이름이나 데이터 형식을 혼용 할 위험이 없습니다. 단점은 더 많은 설정을 코딩해야하며 런타임에 추가 할 수 없다는 것입니다.

객체 지향 버전을 사용하면 런타임에 새로운 설정을 추가 할 수 있다는 이점이 있습니다. 그러나 강력한 형식의 이름과 값이 없습니다. 문자열 식별자에주의해야합니다. 값을 얻을 때 이전에 저장된 데이터 유형을 알아야합니다.

완전한 기능 구현의 코드는 여기에서 찾을 수 있습니다 .


2

예, 구성 을 저장할 수 는 있지만 선택한 방식에 따라 다릅니다. 보유한 옵션을 이해할 수 있도록 기술적 차이점을 설명하겠습니다.

사용할지 여부를 먼저, 당신은 구별 할 필요가 applicationSettings 또는 appSettings는을 당신에 *.exe.config(일명 App.config있다 - Visual Studio에서) 파일 근본적인 차이는 여기에 설명되고 .

둘 다 변경 사항을 저장하는 다른 방법을 제공합니다.

  • appSettings는이 읽고 (를 통해 설정 파일에 직접 작성할 수 있도록 config.Save(ConfigurationSaveMode.Modified);구성은 다음과 같이 정의된다, 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). 으로 한스 옆모습이 언급 한 그의 대답에 일반적으로 사용자가 프로그램 파일에 대한 권한을 제한하고 프롬프트 UAC를 호출하지 않고 쓸 수 없기 때문에,이입니다. 단점은 나중에 구성 키를 추가하는 경우 모든 사용자 프로필과 동기화해야한다는 것입니다.

참고 : 질문에서 언급했듯이 세 번째 옵션 이 있습니다. 구성 파일을 XML 문서 로 취급하는 경우 System.Xml.Linq.XDocument클래스 를 사용하여 구성 파일을 로드, 수정 및 저장할 수 있습니다. 사용자 정의 XML 파일을 사용할 필요는 없습니다. 기존 구성 파일을 읽을 수 있습니다. 요소를 쿼리하기 위해 Linq 쿼리를 사용할 수도 있습니다. 나는 여기 에 예제를 주었고 GetApplicationSetting대답에서 함수를 확인하십시오 .

값을 보호하기 위해 암호화가 필요한 경우이 답변을 확인하십시오 .


이 훌륭한 답변에 감사드립니다.
NoChance

2
@NoChance-천만에요, 기꺼이 도와 드리겠습니다!
매트

좋은! 마침내 모든 것을 알아 냈습니다 😂😂😂
Momoro

1
@Momoro-잘 들었습니다! ;-)
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();
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.