2008-08-25 54 views
52

Tengo una aplicación .NET 2.0 Windows Forms. ¿Dónde está el mejor lugar para la configuración del usuario de la tienda (teniendo en cuenta las pautas de Windows)?¿Cuál es la mejor forma de almacenar la configuración del usuario para una aplicación .NET?

Algunas personas señalaron Application.LocalUserAppDataPath. Sin embargo, lo que crea una estructura de carpetas como:

C: \ Documents and Settings \ nombre_usuario \ Configuración local \ Data \ product_name \ PRODUCT_VERSION \

Si libero versión \ company_name 1 de mi aplicación y almacenar un archivo XML allí, luego lanzar la versión 2, que 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.

+0

Creo que [este artículo] (http://blog.kowalczyk.info/kb/getting-user-specific-application-data-directory-for-.net-winforms-apps.html) cubre la solución. –

+0

[Enlace actualizado] (https://blog.kowalczyk.info/article/10b/Getting-user-specific-application-data-directory.html) del comentario de Jorges. – tm1

Respuesta

74

Me encanta usar el built-in Application Settings. A continuación, han construido en la ayuda para el uso del diseñador de configuración si desea en tiempo de diseño o en tiempo de ejecución a utilizar:

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

Lo hace almacenar la configuración en una estructura de carpetas similar a la que usted describe (con la versión en el camino). Sin embargo, con una simple llamada a:

Properties.Settings.Default.Upgrade(); 

La aplicación va a tirar de todos los ajustes de las versiones anteriores de guardar en

+1

Gracias por la sugerencia de actualización(). –

+3

lo único molesto acerca de 'Settings.Default' es que debe crearlos manualmente de antemano, a diferencia de' NSUserDefaults' en Cocoa que devuelve nil si no existe una configuración. – Ali

+3

¿En qué espacio de nombres está esto? No parece tener acceso a un objeto de Configuración en mi.NET 4 winforms app. – NickG

1

Los ajustes son pares clave-valor estándar (string-string). Podría envolverlos en un archivo XML, si eso ayuda.

Prefiero utilizar 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.

0

Me gustaría ir a la lista de carpetas que publicó a excepción de la versión del producto. No desea restablecer la configuración después de que se lanza una actualización.

En realidad me estoy alejando del registro para 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 ser mucho más amigable con 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 a esto, pero ninguno de los datos que estoy ordenando es fundamental para esa causa, y no estoy sufriendo ningún golpe de rendimiento debido al tamaño de la aplicación.

2

Un enfoque que ha funcionado para mí en el pasado ha sido la creación de una clase de ajustes y. use serialización XML para escribirlo 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 reproche haber reinventado 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.

+0

Si está dispuesto a crear una serialización XML personalizada, ¿por qué no serializarla en una sola configuración de aplicación? De esta forma, puedes utilizar la infraestructura de configuración de la aplicación. Cree un convertidor de clase o tipo serializable y luego importe la clase usando el diálogo de configuración de la aplicación. –

4

O escriba su configuración en un archivo xml y guárdela usando Isolated Storage. 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.

0

El almacenamiento aislado se usa principalmente para aplicaciones distribuidas usando 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.

Ryan Farley has it right.

7

. 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, se me ocurrió my own settings code for Windows Forms. No es tan ingenioso como el que viene con .NET, pero es más flexible y lo uso todo el tiempo.

1

que probar algunos métodos para guardar mi configuración para archivos de texto simple y me encontré mejor manera:

archivo almacenado en la carpeta de aplicaciones, con el uso, settings.txt: (en el interior archivo de configuración aprobada comentarios, intente // comentario)

// obtener configuración valoran

Settings.Get("name", "Ivan"); 

// para establecer la configuración valoran

Settings.Set("name", "John"); 

usando:

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Windows.Forms; 

// puede almacenar también en nombre de la sección, para usar sólo tiene que añadir Conjunto sección de nombre (section_name, nombre, valor) y Get (section_name, nombre, valor)

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); 
    } 
} 
Cuestiones relacionadas