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.
La verdad es que utilizar la API de ClickOnce está tirado, y nos permite hacer cosas tan chulas como esta:
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 **
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.