ClickOnce, actualizar una aplicación ‘on demand’

Una de las grandes características disponibles a partir de VS2005 fue la tecnología ClickOnce, que permitía distribuir aplicaciones de forma asombrosamente sencilla. Hoy no nos vamos a dedicar a explicar con detalle esta tecnología (supongo que muchos de vosotros ya la estaréis utilizando), si no que nos vamos a centrar en extender su funcionalidad para comprobar por código si existen nuevas versiones publicadas, y en caso afirmativo actualizar la misma.

ClickOnceAPI

La verdad es que utilizar la API de ClickOnce está tirado, y nos permite hacer cosas tan chulas como esta:

UpdateAvailable

El código para comprobar si existen actualizaciones es el siguiente:

private static void InstallUpdateSyncWithInfo()
{
    UpdateCheckInfo info = null;
 
    if (ApplicationDeployment.IsNetworkDeployed)
    {
        ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
 
        try
        {
            info = ad.CheckForDetailedUpdate();
        }
        catch (DeploymentDownloadException dde)
        {
            MessageBox.Show(String.Format(
                Properties.Settings.Default.CLICKONCE_CANT_DOWNLOAD_UPDATE, 
                dde.Message, MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation));
            return;
        }
        catch (InvalidDeploymentException ide)
        {
            MessageBox.Show(String.Format(
                Properties.Settings.Default.CLICKONCE_CORRUPT_DEPLOYMENT, 
                ide.Message, MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation));
            return;
        }
        catch (InvalidOperationException ioe)
        {
            MessageBox.Show(String.Format(
                Properties.Settings.Default.CLICKONCE_NO_CLICKONCE_DEPLOYMENT, 
                ioe.Message, MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation));
            return;
        }
 
        if (info.UpdateAvailable)
        {
            Boolean doUpdate = true;
 
            if (!info.IsUpdateRequired)
            {
                DialogResult dr = MessageBox.Show(
                    string.Format(Properties.Settings.Default.CLICKONCE_UPDATE_AVAILABLE, 
                    info.AvailableVersion.ToString()),
                    Application.ProductName, MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Information);
                if (!(DialogResult.OK == dr))
                {
                    doUpdate = false;
                }
            }
            else
            {
                MessageBox.Show(
                    String.Format(Properties.Settings.Default.CLICKONCE_MANDATORY_UPDATE,
                    info.MinimumRequiredVersion.ToString(),
                    ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString()),
                    Application.ProductName, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
 
            if (doUpdate)
            {
                try
                {
                    ad.Update();
                    MessageBox.Show(Properties.Settings.Default.CLICKONCE_UPDATE_SUCCESSFULLY,
                        Application.ProductName, MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    Application.Restart();
                }
                catch (DeploymentDownloadException dde)
                {
                    MessageBox.Show(String.Format(
                        Properties.Settings.Default.CLICKONCE_CANT_INSTALL_UPDATE, 
                        dde.Message, MessageBoxButtons.OK,
                        MessageBoxIcon.Exclamation));
                    return;
                }
            }
        }
        else
        {
            MessageBox.Show(Properties.Settings.Default.CLICKONCE_NO_UPDATES_AVAILABLES,
                Application.ProductName, MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }
    }
}

Basta acompañar este código con unas constantes definidas en los settings de nuestra aplicación y voilá!

A continuación os muestro un ejemplo del fichero de settings por si alguno se lo quiere personalizar:

<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" 
  CurrentProfile="(Default)" GeneratedClassNamespace="TestClickOnceDeployment.Properties" GeneratedClassName="Settings">
  <Profiles />
  <Settings>
    <Setting Name="CLICKONCE_CANT_DOWNLOAD_UPDATE" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      La nueva versión de la aplicación no puede ser descargada en estos momentos.\n\
      Por favor, revise la connexión de red o pruébelo un poco más tarde. Error: {0}</Value>
    </Setting>
    <Setting Name="CLICKONCE_CORRUPT_DEPLOYMENT" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      No se puede verificar la nueva versión de la aplicación. La publicación ClickOnce está corrupta. 
      Por favor, redistribuya de nuevo la aplicación i pruébelo un poco más tarde. Error: {0}</Value>
    </Setting>
    <Setting Name="CLICKONCE_NO_CLICKONCE_DEPLOYMENT" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      La aplicación no se puede actualizar. Parece ser que la publicación no es una aplicación ClickOnce válida. Error: {0}</Value>
    </Setting>
    <Setting Name="CLICKONCE_UPDATE_AVAILABLE" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      Se ha encontrado disponible una actualización. Desea actualitzar la aplicación a la versión '{0}'?</Value>
    </Setting>
    <Setting Name="CLICKONCE_MANDATORY_UPDATE" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      Esta aplicación ha detectado que la versión mínima de l'aplicació es la versión '{0}', 
      i actualmente se está utilizando la versión '{1}'. 
      A continuación la aplicación se actualitzará y reiniciará.</Value>
    </Setting>
    <Setting Name="CLICKONCE_UPDATE_SUCCESSFULLY" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      La aplicación se ha actualitzado correctamente, y a continuación se reiniciará.</Value>
    </Setting>
    <Setting Name="CLICKONCE_CANT_INSTALL_UPDATE" Type="System.String" Scope="Application">
      <Value Profile="(Default)">
      La nueva versión de la aplicación no se puede instalar en estos momentos.\n\n
      Por favor, revise la connexión de red o pruébelo un poco más tarde. Error: {0}</Value>
    </Setting>
    <Setting Name="CLICKONCE_NO_UPDATES_AVAILABLES" Type="System.String" Scope="Application">
      <Value Profile="(Default)">No se han encontrado actualitzacions disponibles de la aplicación.</Value>
    </Setting>
  </Settings>
</SettingsFile>

Y eso es todo… Un saludo desde Andorra!

** crossposting desde el blog de Lluís Franco en geeks.ms **

One thought on “ClickOnce, actualizar una aplicación ‘on demand’

  1. Una duda que tengo con las aplicaciones ClickOnce:

    Cómo se le pasa un parámetro por línea de comandos a tu aplicación click once, en la documentacion de MSDN podemos encontrar:
    http://msdn.microsoft.com/es-es/library/ms172242.aspx

    Pero no entiendo como implementarlo para pasarle el parámetro a nuestra aplicacion de escritorio, tiene que conectarse al servidor mediante esa URL? y si el servidor de actualizaciones está caido? no se le puede pasar el parámentro?
    Mi aplicacion ClickOnce es del tipo sin conexion.

    Un saludo.

Leave a Reply

Your email address will not be published. Required fields are marked *


*