문제

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

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

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

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

.NET 구성 파일에 값을 다시 저장할 수 없다는 내용을 읽었습니다.레지스트리에 관해서는 가능한 한 멀리 떨어져 있고 싶습니다.

이는 구성 설정을 저장하기 위해 사용자 정의 XML 파일을 사용해야 한다는 의미입니까?그렇다면 그 코드예제(C#)를 보고 싶습니다.

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

도움이 되었습니까?

해결책

Visual Studio에서 작업하면 지속 가능한 설정을 쉽게 얻을 수 있습니다. Solution Explorer에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택하십시오. 설정 탭을 선택하고 설정이 존재하지 않으면 하이퍼 링크를 클릭하십시오. 설정 탭을 사용하여 응용 프로그램 설정을 만듭니다. 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 양식 및 기타 프로젝트 유형 모두에 적용됩니다.

설정해야합니다 범위 설정 속성. 애플리케이션 범위를 선택하면 Settings.Default. <귀하의 속성>이 읽기 전용입니다.

다른 팁

실행 파일과 동일한 디렉토리 내의 파일에 저장을 계획하고 있다면 다음을 사용하는 멋진 솔루션이 있습니다. 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;
        }
    }
}

레지스트리는 아니에요. 응용 프로그램을 사용하는 사용자가 레지스트리에 편지를 쓸 수있는 충분한 권한이 있는지 확실하지 않습니다.

당신은 사용할 수 있습니다 app.config 파일 응용 프로그램 수준 설정을 저장하는 파일 (응용 프로그램을 사용하는 각 사용자마다 동일).

사용자 별 설정을 XML 파일에 저장하여 저장됩니다. 고립 된 스토리지 또는 Specialfolder.applicationData 예배 규칙서.

그 옆에 .NET 2.0에서 값을 다시 저장할 수 있습니다. app.config 파일.

그만큼 ApplicationSettings 클래스는 app.config 파일에 대한 저장 설정을 지원하지 않습니다. 이는 제대로 안전한 사용자 계정으로 실행되는 앱 (Vista UAC)이 프로그램의 설치 폴더에 대한 쓰기 액세스 권한이 없습니다.

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

레지스트리/구성 세팅/XML 인수는 여전히 매우 활성화 된 것 같습니다. 기술이 진행됨에 따라 나는 그들 모두를 사용했지만 내가 가장 좋아하는 것은 Threed의 시스템 결합 고립 된 스토리지.

다음 샘플을 사용하면 분리 된 스토리지의 파일에 특성이라는 이름을 지정하는 객체를 저장할 수 있습니다. 와 같은:

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

저는 이를 위해 제가 만든 라이브러리를 공유하고 싶었습니다.작은 라이브러리이지만 .settings 파일에 비해 크게 개선되었습니다(IMHO).

도서관이라고 합니다 적(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 파일과 비교한 이점: 코드가 상당히 적고, 각 속성만 언급하면 ​​되므로 오류 발생 가능성도 훨씬 적습니다. 한 번.

설정 파일을 사용하면 각 속성을 언급해야 합니다. 다섯 타임스:명시적으로 속성을 생성할 때 한 번, 값을 앞뒤로 복사하는 코드에서 추가로 네 번.

저장, 직렬화 등완전히 구성 가능합니다.IOC 컨테이너에 의해 대상 객체가 생성되면 [연결][]하여 해결하는 모든 객체에 자동으로 추적을 적용할 수 있으므로 속성을 지속성으로 만들기 위해 수행해야 하는 모든 작업은 [Trackable] 속성을 적용하는 것뿐입니다. 그 위에.

고도로 구성 가능하며 다음을 구성할 수 있습니다.- 전체적으로 또는 각 추적 된 개체에 대해 데이터가 지속되고 적용되는 경우 - 직렬화 된 방법 - 저장된 위치 (예 :파일, 데이터베이스, 온라인, 고립 된 스토리지, 레지스트리) - 부동산에 대한 데이터 적용/지속을 취소 할 수있는 규칙

저를 믿으세요. 도서관은 최고 수준입니다!

간단한 방법은 구성 데이터 객체를 사용하여 로컬 폴더의 응용 프로그램 이름을 가진 XML 파일로 저장하고 시작시 다시 읽는 것입니다.

다음은 양식의 위치와 크기를 저장하는 예입니다.

구성 DataObject는 강력하게 입력하고 사용하기 쉽습니다.

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

제안 된 사용 솔루션이 마음에 들지 않습니다 web.config 또는 app.config. 자신의 XML을 읽으십시오. 살펴보십시오 XML 설정 파일 - 더 이상 web.config가 없습니다.

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

  • .NET 4.0 동적을 사용하는 경우이 라이브러리는 실제로 사용하기 쉽습니다 (원하는대로 직렬화, 사형화, 중첩 된 객체 지원 및 주문 출력 + 여러 설정을 하나로 병합). JSONCONFIG (사용법은 ApplicationStingSbase와 동일합니다)
  • .NET Yaml 구성 라이브러리의 경우 ... JSONCONFIG만큼 사용하기 쉬운 것을 찾지 못했습니다.

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

여러 설정을 사용하도록 선택하면 해당 설정을 병합 할 수 있습니다. 자신의 규칙을 사용할 수 있습니다. 마지막 규칙은 값을 무시합니다.

"이것은 구성 설정을 저장하기 위해 사용자 정의 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

도움이되기를 바랍니다.

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

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

때로는 기존의 Web.Config 또는 App.Config 파일에 보관 된 설정을 제거하고 싶을 때가 있습니다. 설정 항목 및 분리 된 데이터 설계의 배포에 대한 더 미세한 입금 제어를 원합니다. 또는 요구 사항은 런타임에 새 항목을 추가 할 수 있어야합니다.

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

  • 강력하게 입력 한 버전
  • 객체 지향 버전.

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

객체 지향 버전의 경우 런타임에 새 설정을 추가 할 수 있다는 장점입니다. 그러나 이름과 값을 강력하게 입력하지 못합니다. 문자열 식별자를 조심해야합니다. 값을 얻을 때 이전에 저장된 데이터 유형을 알아야합니다.

완전히 기능적인 구현의 코드를 찾을 수 있습니다. 여기.

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();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top