Example of ClickOnce Deployment

20 May 2012 by

Without any tool, deployment of desktop application is really painful. In the old day, developers need to write an auto-updated application by themselves. However, now ClickOnce, Microsoft product, could leverage this task easily. ClickOnce allows user to setup and run program directly from a webpage. The deployment files will be published to the a friendly URL and then access at the client computer. There is an option for client to check update every program run or any point in the program. This technique is very similar to Java Web Start.

I will show how to achieve it in this demo.

 1. Architecture

ClickOnce Architecture

2. Source Code

I just want to show a snapshot of code in LoginForm and UpdateForm.

LoginForm

using System;
using System.Deployment.Application;
using System.Windows.Forms;

namespace RVD.Win.View
{
  public partial class LoginForm : Form
  {
    public LoginForm()
    {
      InitializeComponent();
    }

    private void LoginForm_Load(object sender, EventArgs e)
    {
      CheckForUpdate();
    }

    private void CheckForUpdate()
    {
      var appDeploy = ApplicationDeployment.CurrentDeployment;

      //Check for update
      var update = appDeploy.CheckForDetailedUpdate();
      if(appDeploy.CheckForUpdate())
      {
        MessageBox.Show(@"The system needs to be updated to version: " + update.AvailableVersion, @"Update",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
        var deployForm = new AppDeployPopup {AppDeploy = appDeploy, IsUpdateAvailable = true};
        deployForm.ShowDialog();

        if (deployForm.ShouldAppRestart)
        {
          Visible = false;
          Close();  
          Application.Restart(); 
        }
      }
    }
  }
}

UpdateForm here, I would call AppDeployPopup. We are invoking
UpdateAsync()
method to update the software asynchronously. This method support two events called AsyncCompletedEvent and DeploymentProgressChangedEvent. We will use this event to show downloading progress in the form as well as closing the form after updating is completed.

using System;
using System.ComponentModel;
using System.Deployment.Application;
using System.Windows.Forms;

namespace RVD.Win.View.Popup
{
  public partial class AppDeployPopup : Form
  {
    public AppDeployPopup()
    {
      InitializeComponent();
    }

    #region Properties

    public ApplicationDeployment AppDeploy { get; set; }

    public bool IsUpdateAvailable { get; set; }

    public bool ShouldAppRestart { get; set; }

    #endregion

    private void AppDeployPopup_Load(object sender, EventArgs e)
    {
      Cursor = Cursors.WaitCursor;

      try
      {
        if (IsUpdateAvailable) BeginUpdate();
      }catch(Exception exception)
      {
        MessageBox.Show(@"Unexpected error during updating this software. \n" + exception.Message);
      }finally
      {
        Cursor = Cursors.Default;
      }
    }

    private void BeginUpdate()
    {

      AppDeploy.UpdateCompleted += new AsyncCompletedEventHandler(AppDeploy_UpdateCompleted);

      AppDeploy.UpdateProgressChanged += new DeploymentProgressChangedEventHandler(AppDeploy_UpdateProgressChanged);

      AppDeploy.UpdateAsync();
    }

    private void AppDeploy_UpdateCompleted(object sender, AsyncCompletedEventArgs e)
    {
      ShouldAppRestart = false;
      if (e.Cancelled)
      {
        MessageBox.Show(@"The update of the application's latest version was cancelled.", @"Warning",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
      }
      else if (e.Error != null)
      {
        MessageBox.Show(@"There was an error during updating. Please contact your system administrator.", @"Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      else
      {
        ShouldAppRestart = true;
      }
      Close();
    }

    private void AppDeploy_UpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
    {
      var progressText = String.Format("Downloading: {0:D}K out of {1:D}K downloaded - {2:D}% complete", e.BytesCompleted/1024,
                                          e.BytesTotal/1024, e.ProgressPercentage);
      lblDownloadStatus.Text = progressText;
      pgbDownload.Value = e.ProgressPercentage;
    }
  }
}

 3. Publish

ClickOnce Publish Page

You should publish the program or iterated update program to location where accessed by IIS for application web deployment. In this example, we publish to ftp server. To see the page, right click on Project in Solution Explorer and then choose Properties.

 

ClickOnce Application Files

Application Files Button

Choose the library required by the program. You have an option to include or exclude those libraries.

 

ClickOnce Prerequisites

Prerequisites Button

Show an option for prerequisites library or program. In this example, we choose to create a setup file for prerequisites. We choose Microsoft .NET Framework 4 and Windows Installer. So if the client does not have these files, it will automatically setup these files first before running our program.

 

ClickOnce Update Page

Update Button

This page will tell how to client check update. In this example, we did not allow any update. However, we have done manually in the source code above. Our code is flexible than the default configuration.

 

ClickOnce Option

Options

This page showing more options on modifying the description of program, deployment, manifest and file association. In this example, I keep it as default except the Deployment webpage.

 

4. Output Files

ClickOnce Output Files

After publishing, some program files will be created in the designed folder. These files is enough for mapping a virtual directory in IIS; so that client can access by friendly URL.

 

5. Configure IIS for the publishing files

ClickOnce IIS Configuration

6. Client Setup

Please use Internet Explorer for full support. Just type URL in the address bar then the setup page will be appeared.

 

ClickOnce Setup Page at Client

ClickOnce Setup Dialog

7. Update at Client

Client checks update on the start up. If update is available it will show the information and perform update.

ClickOnce Showing Update Is Available

ClickOnce Updating is in Progress

Tags:

No responses yet

Leave a Reply