el Guille, la Web del Visual Basic, C#, .NET y más...

Recuperar los valores de configuración de la versión anterior

 
Publicado el 24/Nov/2008
Actualizado el 24/Nov/2008
Autor: Guillermo 'guille' Som

Recuperar los valores de configuración de la versión anterior con código para Visual Basic y C# (aunque solo es válido para los compiladores que usan .NET Framework 2.0 o superior).



 

La batallita:

A partir de .NET Framework 2.0, cuando usamos los datos de configuración por medio de "la clase" Settings (en VB usando My.Settings y en C# usando Properties.Settings.Default), los datos que se almacenan dependen de la versión del ensamblado, es decir, si cambiamos la versión de nuestro ejecutable se usarán otros datos diferentes. Lo que aquí te cuento es para recuperar desde una versión posterior los datos que se hubieran guardado con la versión anterior, de esa forma, el usuario mantendrá los mismos datos a pesar de que se cambia la versión.

¿No sabes de qué te hablo?

Te explico: Cuando usas los datos de configuración a nivel de usuario (que son los que se pueden modificar), esos datos se guardan en una carpeta del directorio del usuario actual. Esa carpeta tiene una estructura predefinida, que para simplificar te diré que está formada (la estructura) por una carpeta con el nombre de la aplicación y dentro de ésta hay otra con la versión actual del ejecutable. Por tanto, si tu aplicación es la versión 1.0.0.0, los datos de configuración estarán en el directorio 1.0.0.0, si cambias la versión del ejecutable a la 1.1.0.0, se creará otra carpeta con ese número y los datos correspondientes a esa nueva versión se guardarán dentro de esa otra carpeta, por tanto, los datos de la versión anterior no estarán disponibles... salvo que sigas leyendo y te enteres cómo conseguir de forma "automatizada" esos datos de la versión anterior.

Vamos a lo que vamos

Pues bien, si sabemos que nuestra aplicación está usando una versión diferente de nuestra aplicación, podemos leer los datos de la versión anterior y usarlos en esa nueva versión.
Esto se puede hacer de dos formas distintas, una de ellas la podemos usar para leer solo algunos de los datos de la configuración (en lugar de leer todos los que hubiera en la versión anterior), y la otra forma es para leer todos los datos de la versión anterior y asignarlos como si ya estuvieran asignados. Esta segunda forma es la recomendada, entre otras cosas porque no dará error si intentáramos leer los datos de una versión anterior cuando en realidad no hay ninguna versión anterior.
Y es que esto último puede que nos pase... porque... ¿cómo sabemos si estamos usando datos que ya se han guardado con anterioridad (de la misma versión) o es la primera vez que vamos a leer los datos (ya sean porque es la primera vez o porque es la primera vez de una nueva versión)?

Te explico lo que yo suelo hacer:
Habitualmente guardo la posición en que está el formulario principal, y para saber si es la primera vez que leo esos datos, suelo asignarle a algunos de esos datos (normalmente al valor de la posición izquierda) un valor inicial de -999, de esa forma (si el valor devuelto por ese valor de la configuración es el valor predeterminado) sé con seguridad que no se han leído los datos. Ya que al cerrar el formulario siempre guardo la posición en los datos de configuración, y salvo que "accidentalmente" tenga un valor de -999, pues... ya sé que si tiene otro valor es que se ha guardado aunque sea una vez los datos de configuración.

De todas formas, no quiero alargar más esto... supongo que si has usado los valores de la configuración, ya habrás tenido oportunidad de ingeniarte la forma de saber si es la primera vez que lees los datos o no.

 

Empecemos por el final, es decir, veamos cómo guardar los datos de configuración cuando el formulario principal de la aplicación se va a cerrar y así sabremos qué datos son los que manejamos.
En el evento FormClosing escribe lo siguiente (se incluye primero el código de Visual Basic y después el de C#):

Private Sub Form1_FormClosing(ByVal sender As Object, _
                              ByVal e As FormClosingEventArgs) _
                              Handles Me.FormClosing
    ' guardar los datos en la configuración

    ' Si el formulario no está en modo normal
    ' guardar los datos de la posición que tenía
    ' antes de minimizar o maximizar
    If WindowState <> FormWindowState.Normal Then
        My.Settings.Left = Me.RestoreBounds.Left
        My.Settings.Top = Me.RestoreBounds.Top

    Else
        My.Settings.Left = Me.Left
        My.Settings.Top = Me.Top

    End If

    My.Settings.Nombre = txtNombre.Text

    ' En VB no es necesario, pero por si alguien cambia
    ' la forma predeterminada de que se auto guarden los datos
    My.Settings.Save()
End Sub

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // guardar los datos en la configuración

    // Si el formulario no está en modo normal
    // guardar los datos de la posición que tenía
    // antes de minimizar o maximizar
    if (WindowState != FormWindowState.Normal)
    {
        Properties.Settings.Default.Left = this.RestoreBounds.Left;
        Properties.Settings.Default.Top = this.RestoreBounds.Top;
    }
    else
    {
        Properties.Settings.Default.Left = this.Left;
        Properties.Settings.Default.Top = this.Top;
    }

    Properties.Settings.Default.Nombre = txtNombre.Text;

    // En VB no es necesario, pero por si alguien cambia
    // la forma predeterminada de que se auto guarden los datos
    Properties.Settings.Default.Save();
}

Como puedes ver, se guardan los valores de la posición izquierda y superior del formulario en dos valores de la configuración llamados Left y Top. También se guarda lo que haya en una caja de textos llamada txtNombre en el valor de configuración llamado Nombre.

En Visual Basic los valores de configuración se manejan desde la propiedad Settings definida en el objeto My, en C# no existe un objeto similar a My, por tanto, para acceder a los valores de la configuración debemos acceder a la propiedad estática (compartida) Default definida en la clase Settings.

En ambos lenguajes los valores de la configuración se guardan como propiedades de la clase Settings (en VB aunque se accede como a una propiedad, en realidad es también una clase llamada Settings, cosas de facilitar las cosas... se supone... lo malo es cuando hay que explicarlo o cuando uno se pone a indagar de dónde salen esas propiedades "mágicas", en fin... ese trabajo extra que tenemos los que usamos Visual Basic). Y en esa misma clase existe el método Save para guardar los valores en el fichero de configuración. En Visual Basic, al menos de forma predeterminada, se hace una llamada a ese método cuando se cierra la aplicación, pero a mi me gusta indicarlo expresamente, así si se cambia esa forma "automatizada" de guardar los valores de configuración, no pasará nada y los datos se guardarán.

Otra cosa que puedes comprobar en ese código es que a la hora de guardar los valores de la posición del formulario se tiene en cuenta si está mostrado en forma normal o está minimizado o maximizado, y es que si no se muestra de forma normal, los valores de la posición puede que no sean los correctos, en esos casos, lo que hago es usar los valores de RestoreBounds para saber cuáles eran antes de que se maximizara o minimizara.

Ya que sabemos qué valores usamos y cómo se guardan, veamos qué habría que hacer para leerlos y en caso de que queramos recuperar los valores de una versión anterior, cómo lo haríamos.

 

Empecemos a complicarnos la vida (y ver lo que quería mostrarte desde que empecé, es que cuando me enrollo no hay quién me pare, jejeje).

Para poder probar esto que te muestro (y sepas cómo funciona) he creado un proyecto (que puedes bajarte) en el cual he añadido un CheckBox para saber si se deben leer los valores de la versión anterior o no. Por supuesto ese CheckBox solo es para usarlo en estas pruebas, ya que no tendría mucha utilidad en una aplicación normal... pero bueno, es para que puedas hacer tus pruebas con los dos modos que te muestro de recuperar la configuración de una versión anterior.

Nota:
En los comentarios del código fuente del formulario principal te explico lo que debes hacer para hacer las pruebas correspondientes y ver cómo funciona todo esto.

Para recuperar los valores de la configuración de una versión anterior, lo más fácil es usar el método Upgrade de la clase Settings, de esa forma, si hay valores de alguna versión anterior, se usarán esos valores y se asignarán todos los valores de configuración con lo que hubiera en esa versión anterior.
Por supuesto la llamada a ese método no debes hacerla siempre, solo la primera vez que leas los datos (recuerda eso que te comenté arriba sobre el valor -999 de una de las propiedades), ya que si siempre recuperas los valores anteriores... pues... como que no tendrás oportunidad de guardar los nuevos valores, ya que el método Upgrade lo que hace es desechar los valores actuales (de la versión actual) y utilizar los que hubiera de una versión anterior.

La otra forma de recuperar valores de configuración de una versión anterior es hacerlo de forma "manual", es decir, recuperar los datos de configuración uno a uno. Esto es práctico cuando no necesitamos recuperar todos los valores. La forma de hacerlo es por medio del método GetPreviousVersion al cual debemos indicarle una cadena con el nombre de la propiedad de la que queremos recuperar el valor de la versión anterior. El problema de este método es que fallará si no existe una versión anterior, por tanto habrá que usarlo con más cuidado y teniendo en cuenta que se puede producir una excepción al intentar acceder a un valor que no existe. Para usar este método no es necesario hacer una llamada a Upgrade, ya que si usamos Upgrade, no es necesario usar GetPreviousVersion, ya que se recuperan todos los valores de la versión anterior, por tanto, sería redundante usar el método GetPreviousVersion después de haber recuperado los datos con Upgrade.
Otro inconveniente que tiene GetPreviousVersion es que el valor devuelto es de tipo Object y habrá que hacer la conversión correspondiente al tipo de datos adecuado (aclarar que esto que acabo de decir solamente es cierto si usamos C# o si usamos VB de la forma recomendada, es decir activando Option Strict, ya que con Option Strict Off las conversiones entre tipos se "intentan" hacer en tiempo de ejecución y aunque en las conversiones de este ejemplo siempre funcionarán las conversiones "automáticas", es recomendable hacerlas de forma explícita, por si falla la conversión saber que ahí es donde se puede producir un error).

Veamos el código que he usado en el evento Load del formulario de la aplicación de ejemplo, en el que se hace la comprobación de si queremos usar los datos de la versión anterior o no. En ese código se muestra tanto el método Upgrade como el método GetPreviousVersion, pero como ya te he comentado antes no se deben usar los dos al mismo tiempo, y de hacerlo, es casi como perder el tiempo, al menos si primero se hace la llamada al método Upgrade... en fin... que salvo que lo necesites de forma expresa, te recomiendo que uses Upgrade y no el otro método... queda dicho.

Este es el código del evento Load, primero para VB, después para C# (aclaración por si alguien aún no distingue el código de uno y otro lenguaje, jejeje):

Private Sub Form1_Load(ByVal sender As Object, _
                       ByVal e As EventArgs) _
                       Handles MyBase.Load

    If chkVersiones.Checked Then
        ' recuperar los datos de la versión anterior
        ' (esto actualizará todos los valores)
        My.Settings.Upgrade()

        ' También se puede hacer
        ' con los valores individuales que nos interesen
        ' por si no queremos recuperarlos todos
        txtNombre.Text = My.Settings.GetPreviousVersion("Nombre").ToString
        Me.Left = CInt(My.Settings.GetPreviousVersion("Left"))
        Me.Top = CInt(My.Settings.GetPreviousVersion("Top"))

        ' La recuperación de los valores anteriores fallará
        ' si se usa GetPreviousVersion desde la primera versión,
        ' sin embargo con Upgrade siempre funcionará.

    Else
        ' La posición solo si se ha guardado anteriormente
        If My.Settings.Left <> -999 Then
            Me.Left = My.Settings.Left
            Me.Top = My.Settings.Top
        End If

        txtNombre.Text = My.Settings.Nombre
    End If

End Sub

 

private void Form1_Load(object sender, EventArgs e)
{
    if (chkVersiones.Checked)
    {
        // recuperar los datos de la versión anterior
        // (esto actualizará todos los valores)
        Properties.Settings.Default.Upgrade();

        // También se puede hacer
        // con los valores individuales que nos interesen
        // por si no queremos recuperarlos todos
        txtNombre.Text = 
            Properties.Settings.Default.GetPreviousVersion("Nombre").ToString();
        this.Left = (int)Properties.Settings.Default.GetPreviousVersion("Left");
        this.Top = (int)Properties.Settings.Default.GetPreviousVersion("Top");

        // La recuperación de los valores anteriores fallará
        // si se usa GetPreviousVersion desde la primera versión,
        // sin embargo con Upgrade siempre funcionará.
    }
    else
    {
        // La posición solo si se ha guardado anteriormente
        if (Properties.Settings.Default.Left != -999)
        {
            this.Left = Properties.Settings.Default.Left;
            this.Top = Properties.Settings.Default.Top;
        }

        txtNombre.Text = Properties.Settings.Default.Nombre;
    }
}

 

Y esto es todo... espero que te haya sido de utilidad y que te sirva para saber cómo recuperar los valores de configuración de una versión anterior... ya que esa era la intención.

Nos vemos.
Guillermo

 


Código de ejemplo (comprimido):

Fichero con el código de ejemplo: settings_varias_versiones.zip - 26.00 KB

Contiene los proyectos para Visual Basic y C# usando Visual Studio 2008 o las versiones Express.

(MD5 checksum: CBAA4EE2348676A4DEDFA13C034D261A)


 


La fecha/hora en el servidor es: 21/11/2024 14:18:02

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024