¿Puedo controlar la ubicación de la configuración de usuario de .NET para evitar perder la configuración en la actualización de la aplicación?

104

Estoy intentando personalizar la ubicación del user.configarchivo. Actualmente se almacena con un hash y un número de versión.

%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\

Quiero que sea independiente de la versión de la aplicación.

%AppData%\[CompanyName]\[ProductName]\

¿Se puede hacer esto y cómo? ¿Cuáles son las implicaciones? ¿Perderá el usuario la configuración de la versión anterior después de la actualización?

Muxa
fuente
Si bien la respuesta de uzbones es informativa con respecto a la ubicación del archivo, creo que la de Ian es más correcta con respecto a la actualización.
Anthony Mastrean
4
@AnthonyMastrean, personalmente creo que cualquier configuración importante no debe depender de la infraestructura de ApplicationSettings proporcionada por Microsoft. Muxa debería almacenar la configuración en un lugar %AppData%\[CompanyName]/[ProductName]donde podamos confiar en que permanecerá.
Ian Boyd
2
Sin duda, mi experiencia continua con la aplicación integrada y la configuración del usuario ha sido terrible. Recomiendo archivos json en appdata o programdata.
Anthony Mastrean
También puede almacenar su configuración en un registro. Consulte stackoverflow.com/a/12127888/1273550 para ver la implementación de la clase de configuración alternativa.
Ravi Patel

Respuestas:

39

Para responder a la primera pregunta, técnicamente puede colocar el archivo donde desee, sin embargo, tendrá que codificarlo usted mismo, ya que el lugar predeterminado al que va el archivo es el primero de sus dos ejemplos. ( enlace a cómo hacerlo usted mismo )

En cuanto a la segunda pregunta, depende de cómo implemente la aplicación. Si implementa a través de un .msi, entonces hay dos hashes en las propiedades del proyecto de instalación (a partir del cual se construye el msi), el 'código de actualización' y el 'código de producto'. Estos determinan cómo se puede instalar msi y si se actualiza, sobrescribe o instala junto con cualquier otra versión de la misma aplicación.

Por ejemplo, si tiene dos versiones de su software y tienen diferentes códigos de 'actualización', entonces para Windows son piezas de software completamente diferentes, independientemente del nombre. Sin embargo, si el código de 'actualización' es el mismo, pero el código de 'producto' es diferente, cuando intente instalar el segundo msi, le preguntará si desea actualizar, momento en el que se supone que debe copiar los valores del configuración antigua a una nueva configuración. Si ambos valores son iguales y el número de versión no cambió, la nueva configuración estará en la misma ubicación que la configuración anterior y no tendrá que hacer nada. Documentación de MSDN

ClickOnce es un poco diferente, porque se basa más en el número de versión de ClickOnce y la ruta de URL, sin embargo, he descubierto que mientras continúe 'Publicando' en la misma ubicación, la nueva versión de la aplicación continuará usando el configuración existente. ( enlace a cómo ClickOnce maneja las actualizaciones )

También sé que hay una manera de fusionar configuraciones manualmente durante la instalación del msi usando scripts de instalación personalizados, pero no recuerdo los pasos exactos para hacerlo ... (vea este enlace para saber cómo hacerlo con un archivo web. config)

uzbones
fuente
¿No es el código de actualización el que se supone que debe permanecer constante y el código de producto el que se supone que debe cambiar entre lanzamientos? blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx
estanford
Doh! tienes razón, no puedo creer que lo entendí al revés (y me tomó 2 años captarlo). Fue como una firma
automática
¿Eso significa que solo el usuario que realiza la instalación obtiene su configuración actualizada?
Micha Wiedenmann
79

Quería agregar este texto citado como referencia para cuando tenga este problema en el futuro. Supuestamente, puede indicar a la infraestructura de ApplicationSettings que copie la configuración de una versión anterior llamando a Upgrade :

Properties.Settings.Value.Upgrade();

De la publicación del blog de preguntas frecuentes de configuración del cliente : ( archivo )

P: ¿Por qué hay un número de versión en la ruta user.config? Si implemento una nueva versión de mi aplicación, ¿no perderá el usuario todas las configuraciones guardadas por la versión anterior?

R: Hay un par de razones por las que la ruta user.config es sensible a la versión.

(1) Para admitir la implementación en paralelo de diferentes versiones de una aplicación (puede hacerlo con Clickonce, por ejemplo). Es posible que diferentes versiones de la aplicación tengan diferentes configuraciones guardadas.

(2) Cuando actualiza una aplicación, es posible que la clase de configuración se haya alterado y no sea compatible con lo que se guardó, lo que puede ocasionar problemas.

Sin embargo, hemos facilitado la actualización de la configuración de una versión anterior de la aplicación a la última. Simplemente llame a ApplicationSettingsBase.Upgrade () y recuperará la configuración de la versión anterior que coincida con la versión actual de la clase y la almacenará en el archivo user.config de la versión actual. También tiene la opción de anular este comportamiento en su clase de configuración o en la implementación de su proveedor.

P: Bien, pero ¿cómo sé cuándo llamar a Upgrade?

A: Buena pregunta. En Clickonce, cuando instala una nueva versión de su aplicación, ApplicationSettingsBase la detectará y actualizará automáticamente la configuración en el momento en que se cargue la configuración. En los casos que no son Clickonce, no hay actualización automática; debe llamar a Upgrade usted mismo. Aquí hay una idea para determinar cuándo llamar a Upgrade:

Tenga una configuración booleana llamada CallUpgrade y asígnele un valor predeterminado de verdadero. Cuando su aplicación se inicia, puede hacer algo como:

if (Properties.Settings.Value.CallUpgrade)
{
   Properties.Settings.Value.Upgrade();
   Properties.Settings.Value.CallUpgrade = false;    
}

Esto garantizará que se llame a Upgrade () solo la primera vez que se ejecute la aplicación después de implementar una nueva versión.

No creo ni por un segundo que realmente pueda funcionar; no hay forma de que Microsoft brinde esta capacidad, pero el método es el mismo.

Ian Boyd
fuente
3
¡ESTO FUNCIONA TOTALMENTE! Usé solo la if(CallUpgrade) { Upgrade(); }declaración simple .
Anthony Mastrean
@Ian Boyd: Me gusta esta idea y estoy totalmente emocionado de tener una solución potencial, sin embargo, estoy confundido sobre una cosa. No Properties.Settings.Value tengo el Properties.Settingspapel, pero ¿me falta algo o es específico para ti?
Paladín refractado
8
Esto funciona bien, pero les recuerdo a los lectores que la ruta de la configuración hasta pero excluyendo el número de versión debe ser la misma. es decir, vea la respuesta de @ Amr. por ejemplo, si se inicia una nueva versión de la aplicación desde una ruta de archivo diferente a la de una versión anterior, entonces Upgradeno funciona.
Stephen Swensen
1
@RefractedPaladin es Properties.Settings.Default.Upgrade()
Stephen Swensen
5
No olvide agregar Properties.Settings.Default.Save();después de cambiarlo a falso :-)
Jeff
32

El archivo user.config se almacena en

c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<verison>

<c:\Documents and Settings>es el directorio de datos del usuario, ya sea sin roaming (Configuración local arriba) o con roaming.
<username>es el nombre de usuario.
<companyname>es el valor CompanyNameAttribute, si está disponible. De lo contrario, ignore este elemento.
<appdomainname>es AppDomain.CurrentDomain.FriendlyName. Por lo general, el nombre predeterminado es .exe.
<eid>es la URL, StrongName o Path, según la evidencia disponible para el hash.
<hash>es un hash SHA1 de evidencia recopilada del CurrentDomain, en el siguiente orden de preferencia:
1. StrongName
2. URL:
si ninguno de estos está disponible, use la ruta .exe.
<version>es el valor AssemblyVersionAttribute de AssemblyInfo.

La descripción completa está aquí http://msdn.microsoft.com/en-us/library/ms379611.aspx

Amr
fuente
4

(Agregaría esto como un comentario a la respuesta de @ Amr, pero todavía no tengo suficiente representante para hacer eso).

La información en el artículo de MSDN es muy clara y parece que aún se aplica. Sin embargo, no menciona que el hash SHA1 se escribe codificado en base 32, en lugar del más típico en base 16.

Creo que el algoritmo que se está utilizando está implementado ToBase32StringSuitableForDirName, que se puede encontrar aquí en la Fuente de referencia de Microsoft .

JulianRendell
fuente