591 votos

¿Cómo puedo guardar la configuración de la aplicación en una aplicación Windows Forms?

Lo que quiero conseguir es muy sencillo: Tengo una aplicación Windows Forms (.NET 3.5) que utiliza una ruta para leer información. Esta ruta puede ser modificada por el usuario, utilizando el formulario de opciones que le proporciono.

Ahora, quiero guardar el valor de la ruta en un archivo para su uso posterior. Esta sería una de las muchas configuraciones guardadas en este archivo. Este archivo se ubicaría directamente en la carpeta de la aplicación.

Tengo entendido que hay tres opciones disponibles:

  • Archivo ConfigurationSettings (appname.exe.config)
  • Registro
  • Archivo XML personalizado

He leído que el archivo de configuración de .NET no está previsto para guardar valores en él. En cuanto al registro, me gustaría alejarme lo más posible de él.

¿Significa esto que debo utilizar un archivo XML personalizado para guardar los ajustes de configuración?

Si es así, me gustaría ver un ejemplo de código de eso (C#).

He visto otras discusiones sobre este tema, pero todavía no lo tengo claro.

601voto

aku Puntos 54867

Si trabajas con Visual Studio, es bastante fácil conseguir configuraciones persistentes. Haga clic con el botón derecho del ratón sobre el proyecto en el Explorador de soluciones y elija Propiedades. Seleccione la pestaña Configuración y haga clic en el hipervínculo si la configuración no existe.

Utilice la pestaña Configuración para crear los ajustes de la aplicación. Visual Studio crea los archivos Settings.settings y Settings.Designer.settings que contienen la clase singleton Settings heredado de ApplicationSettingsBase . Puede acceder a esta clase desde su código para leer/escribir la configuración de la aplicación:

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

Esta técnica es aplicable tanto para la consola como para Windows Forms y otros tipos de proyectos.

Tenga en cuenta que debe establecer el alcance de su configuración. Si selecciona el ámbito de la aplicación, Settings.Default.<su propiedad> será de sólo lectura.

Referencia: Cómo: escribir la configuración del usuario en tiempo de ejecución con C# - Microsoft Docs

95voto

threed Puntos 2131

Si está planeando guardar en un archivo dentro del mismo directorio que su ejecutable, aquí hay una buena solución que utiliza el JSON formato:

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

68voto

Frederik Gheysels Puntos 36354

El registro es un imposible. No estás seguro de que el usuario que utiliza tu aplicación tenga suficientes derechos para escribir en el registro.

Puede utilizar el app.config para guardar la configuración a nivel de aplicación (que es la misma para cada usuario que utiliza su aplicación).

Almacenaría la configuración específica del usuario en un archivo XML, que se guardaría en Almacenamiento aislado o en el SpecialFolder.ApplicationData directorio.

Además, a partir de .NET 2.0, es posible almacenar valores en el app.config archivo.

20voto

Hans Passant Puntos 475940

El ApplicationSettings no permite guardar la configuración en el archivo app.config archivo. Esto es en gran medida por diseño; las aplicaciones que se ejecutan con una cuenta de usuario debidamente protegida (piense en el UAC de Vista) no tienen acceso de escritura a la carpeta de instalación del programa.

Puedes luchar contra el sistema con el ConfigurationManager clase. Pero la solución trivial es ir al diseñador de configuraciones y cambiar el alcance de la configuración a Usuario. Si eso causa dificultades (digamos que el ajuste es relevante para todos los usuarios), debe poner su función de Opciones en un programa separado para que pueda pedir la solicitud de elevación de privilegios. O renunciar a usar un ajuste.

18voto

Boczek Puntos 61

El argumento del registro/configuraciónSettings/XML todavía parece muy activo. Los he utilizado todos, ya que la tecnología ha progresado, pero mi favorito se basa en El sistema de Threed combinado con Almacenamiento aislado .

El siguiente ejemplo permite el almacenamiento de un objeto llamado propiedades a un archivo en el almacenamiento aislado. Por ejemplo:

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

Las propiedades pueden ser recuperadas usando:

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

Es sólo una muestra, no sugiere las mejores prácticas.

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

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X