c# - org - ¿Cuál es la mejor manera de almacenar la configuración del usuario para una aplicación.NET?
mapwindows 5 (8)
Tengo una aplicación .NET 2.0 de Windows Forms. ¿Dónde está el mejor lugar para la configuración del usuario de la tienda (teniendo en cuenta las pautas de Windows)?
Algunas personas señalaron Application.LocalUserAppDataPath
. Sin embargo, eso crea una estructura de carpetas como:
C: / Documents and Settings / user_name / Configuración local / Application Data / company_name / product_name / product_version /
Si lanzo la versión 1 de mi aplicación y almaceno un archivo XML allí, luego lanzo la versión 2, eso cambiaría a una carpeta diferente, ¿verdad? Preferiría tener una sola carpeta, por usuario, para almacenar la configuración, independientemente de la versión de la aplicación.
El almacenamiento aislado se utiliza principalmente para aplicaciones distribuidas con ClickOnce y se ejecutan en un entorno seguro. La ruta base está decidida para ti y no podrás inferirla en tu código. La ruta será algo así como "/ LocalSettings / ApplicationData / IsolatedStorage / ejwnwe.302 / kfiwemqi.owx / url.asdaiojwejoieajae ....", no tan amigable. Su espacio de almacenamiento también es limitado.
Intento algunos métodos para almacenar mi configuración simplemente archivo de texto y encontré la mejor manera:
archivo almacenado en la carpeta de la aplicación, para el uso, settings.txt : (dentro de los archivos de configuración, comentarios aprobados, intente // comentar)
// para obtener valor de configuración
Settings.Get("name", "Ivan");
// para establecer el valor de configuración
Settings.Set("name", "John");
utilizando:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
// puede almacenar también con el nombre de la sección, para usar simplemente agregar la sección de nombre Establecer (section_name, name, value) y Get (section_name, name, value)
public static class Settings
{
private static string SECTION = typeof(Settings).Namespace;//"SETTINGS";
private static string settingsPath = Application.StartupPath.ToString() + "//settings.txt";
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public static String GetString(String name)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath);
return temp.ToString();
}
public static String Get(String name, String defVal)
{
return Get(SECTION,name,defVal);
}
public static String Get(string _SECTION, String name, String defVal)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(_SECTION, name, "", temp, 255, settingsPath);
return temp.ToString();
}
public static Boolean Get(String name, Boolean defVal)
{
return Get(SECTION, name, defVal);
}
public static Boolean Get(string _SECTION, String name, Boolean defVal)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(_SECTION,name,"",temp,255,settingsPath);
bool retval=false;
if (bool.TryParse(temp.ToString(),out retval))
{
return retval;
} else
{
return retval;
}
}
public static int Get(String name, int defVal)
{
return Get(SECTION, name, defVal);
}
public static int Get(string _SECTION, String name, int defVal)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath);
int retval=0;
if (int.TryParse(temp.ToString(),out retval))
{
return retval;
} else
{
return retval;
}
}
public static void Set(String name, String val)
{
Set(SECTION, name,val);
}
public static void Set(string _SECTION, String name, String val)
{
WritePrivateProfileString(_SECTION, name, val, settingsPath);
}
public static void Set(String name, Boolean val)
{
Set(SECTION, name, val);
}
public static void Set(string _SECTION, String name, Boolean val)
{
WritePrivateProfileString(_SECTION, name, val.ToString(), settingsPath);
}
public static void Set(String name, int val)
{
Set(SECTION, name, val);
}
public static void Set(string _SECTION,String name, int val)
{
WritePrivateProfileString(SECTION, name, val.ToString(), settingsPath);
}
}
Las aplicaciones .NET tienen un mecanismo de configuración integrado que es fácil de usar. El problema con esto, en mi opinión, es que almacena esas configuraciones en un directorio bastante oscuro y los usuarios finales no podrán encontrarlas. Además, el cambio de la depuración a la versión de lanzamiento cambia la ubicación de este directorio, lo que significa que cualquier configuración guardada en una configuración se pierde en la otra.
Por estas y otras razones, ideé mi propio código de configuración para Windows Forms . No es tan ingenioso como el que viene con .NET, pero es más flexible y lo uso todo el tiempo.
Los ajustes son pares clave-valor estándar (string-string). Podría envolverlos en un archivo XML, si eso ayuda.
Prefiero usar el sistema de archivos en lugar del registro. Parece ser más fácil de mantener. En los escenarios de soporte, si el usuario necesita abrir / cambiar manualmente la configuración, sería más fácil si está en el sistema de archivos.
Me encanta usar la configuración de la aplicación integrada. Luego, ha incorporado soporte para utilizar el diseñador de configuraciones si lo desea en tiempo de diseño, o en tiempo de ejecución para usar:
// read setting
string setting1 = (string)Settings.Default["MySetting1"];
// save setting
Settings.Default["MySetting2"] = "My Setting Value";
// you can force a save with
Properties.Settings.Default.Save();
Almacena las configuraciones en una estructura de carpetas similar a la que describes (con la versión en la ruta). Sin embargo, con una simple llamada a:
Properties.Settings.Default.Upgrade();
La aplicación seleccionará todas las configuraciones de versiones anteriores para guardarlas.
Me gustaría ir a la lista de carpetas que publicó, excepto por la versión del producto. No desea restablecer la configuración después de que se lanza una actualización.
De hecho, me estoy alejando del registro de la configuración del usuario debido al factor de depuración / huella. Actualmente solo estoy almacenando algunas configuraciones básicas (tamaño de ventana, posición, versión de un archivo de datos) en el registro, y me he encontrado con más problemas si una actualización falla o si un usuario pierde un segundo monitor y ahí es donde la aplicación se estaba abriendo a. Algunos de ellos son lo suficientemente inteligentes como para entender regedit, pero para el resto tienen que volver a instalarlos, lo cual es rápido, pero creo que se quejan un poco. Con la versión basada en archivos, todo lo que tendría que hacer es hacer que abran un archivo XML en el Bloc de notas y hacer un ajuste rápido.
Además, estoy buscando hacer que mi aplicación se pueda ejecutar desde una unidad flash USB, y tener la configuración vinculada al archivo parece mucho más amigable para ese proceso. Estoy seguro de que puedo hacer algo de código para verificar / limpiar el registro, pero creo que la mayoría de nosotros ya estamos cansados del desorden del registro que parece devorar nuestras máquinas hoy en día.
Sé que hay algunas soluciones de seguridad para esto, pero ninguno de los datos que estoy ordenando es tan crítico para esa causa, y no estoy sufriendo ningún golpe de rendimiento debido al tamaño de la aplicación.
O escriba su configuración en un archivo xml y guárdela usando Almacenamiento aislado . Dependiendo de la tienda que use, la guarda en la carpeta de Datos de la aplicación. También puede elegir una tienda habilitada para itinerancia, lo que significa que cuando el usuario inicia sesión en una computadora diferente, la configuración se mueve con ellos.
Un enfoque que me ha funcionado en el pasado ha sido crear una clase de configuración y usar la serialización XML para escribirla en el sistema de archivos. Puede ampliar este concepto creando una colección de objetos de configuración y serializándolos. Tendría todos sus ajustes para todos los usuarios en un solo lugar sin tener que preocuparse por la administración del sistema de archivos.
Antes de que alguien me critique por reinventar parcialmente la rueda, permítanme decir algunas cosas. Por un lado, son solo unas pocas líneas de código para serializar y escribir el archivo. En segundo lugar, si tiene un objeto que contiene su configuración, no tiene que realizar varias llamadas al objeto appSettings cuando carga su aplicación. Y, por último, es muy fácil agregar elementos que representen el estado de su aplicación, lo que le permite reanudar una tarea de larga ejecución cuando la aplicación se carga a continuación.