ApplicationDeployment Class
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Supports updates of the current deployment programmatically, and handles on-demand downloading of files. This class cannot be inherited.
public ref class ApplicationDeployment sealed
public sealed class ApplicationDeployment
type ApplicationDeployment = class
Public NotInheritable Class ApplicationDeployment
- Inheritance
-
ApplicationDeployment
Examples
The following code example determines at application load time whether a new update is available; if a required update is available, the code example installs the update asynchronously. This code should be added to a form that contains a TextBox named downloadStatus
.
private:
long sizeOfUpdate;
private:
void Form1_Load(Object^ sender, System::EventArgs^ e)
{
DoUpdate();
}
public:
void DoUpdate()
{
if (ApplicationDeployment::IsNetworkDeployed)
{
ApplicationDeployment^ currentAppDeployment =
ApplicationDeployment::CurrentDeployment;
currentAppDeployment->CheckForUpdateCompleted +=
gcnew CheckForUpdateCompletedEventHandler(
this, &Form1::currentDeploy_CheckForUpdateCompleted);
currentAppDeployment->CheckForUpdateAsync();
}
}
// If update is available, fetch it.
void currentDeploy_CheckForUpdateCompleted(Object^ sender,
CheckForUpdateCompletedEventArgs^ e)
{
if (nullptr != e->Error)
{
// Log error.
return;
}
if (e->UpdateAvailable)
{
sizeOfUpdate = (long) e->UpdateSizeBytes;
if (!e->IsUpdateRequired)
{
System::Windows::Forms::DialogResult
updateDialogueResult = MessageBox::Show(
"An update is available.Would you like to update the" +
" application now?", "Update Available",
MessageBoxButtons::OKCancel);
if (System::Windows::Forms::DialogResult::OK ==
updateDialogueResult)
{
BeginUpdate();
}
}
else
{
BeginUpdate();
}
}
}
void BeginUpdate()
{
ApplicationDeployment^ ad = ApplicationDeployment::CurrentDeployment;
ad->UpdateCompleted +=
gcnew AsyncCompletedEventHandler(
this, &Form1::CurrentDeployment_UpdateCompleted);
// Indicate progress in the application's status bar.
ad->UpdateProgressChanged +=
gcnew DeploymentProgressChangedEventHandler(this,
&Form1::ad_ProgressChanged);
ad->UpdateAsync();
}
void CurrentDeployment_UpdateCompleted(Object^ sender,
AsyncCompletedEventArgs^ e)
{
if (!e->Cancelled)
{
if (nullptr != e->Error)
{
System::Windows::Forms::DialogResult
restartDialogueResult = MessageBox::Show(
"The application has been updated. Restart?",
"Restart Application",
MessageBoxButtons::OKCancel);
if (System::Windows::Forms::DialogResult::OK ==
restartDialogueResult)
{
Application::Restart();
}
}
else
{
// Replace with your own error reporting or logging.
MessageBox::Show(
"The application encountered an error in downloading" +
" the latest update. Error: {0}",
e->Error->Message);
}
}
else
{
// Replace with your own error reporting or logging.
MessageBox::Show("The update of the application's latest" +
" version was cancelled.");
}
}
void ad_ProgressChanged(Object^ sender,
DeploymentProgressChangedEventArgs^ e)
{
String^ progressText =
String::Format(
"{0:D}K out of {1:D}K downloaded - {2:D}% complete",
e->BytesCompleted / 1024, e->BytesTotal / 1024,
e->ProgressPercentage);
statusStrip1->Text = progressText;
}
long sizeOfUpdate = 0;
private void UpdateApplication()
{
if (ApplicationDeployment.IsNetworkDeployed)
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(ad_CheckForUpdateCompleted);
ad.CheckForUpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_CheckForUpdateProgressChanged);
ad.CheckForUpdateAsync();
}
}
void ad_CheckForUpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
{
downloadStatus.Text = String.Format("Downloading: {0}. {1:D}K of {2:D}K downloaded.", GetProgressString(e.State), e.BytesCompleted/1024, e.BytesTotal/1024);
}
string GetProgressString(DeploymentProgressState state)
{
if (state == DeploymentProgressState.DownloadingApplicationFiles)
{
return "application files";
}
else if (state == DeploymentProgressState.DownloadingApplicationInformation)
{
return "application manifest";
}
else
{
return "deployment manifest";
}
}
void ad_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show("ERROR: Could not retrieve new version of the application. Reason: \n" + e.Error.Message + "\nPlease report this error to the system administrator.");
return;
}
else if (e.Cancelled == true)
{
MessageBox.Show("The update was cancelled.");
}
// Ask the user if they would like to update the application now.
if (e.UpdateAvailable)
{
sizeOfUpdate = e.UpdateSizeBytes;
if (!e.IsUpdateRequired)
{
DialogResult dr = MessageBox.Show("An update is available. Would you like to update the application now?\n\nEstimated Download Time: ", "Update Available", MessageBoxButtons.OKCancel);
if (DialogResult.OK == dr)
{
BeginUpdate();
}
}
else
{
MessageBox.Show("A mandatory update is available for your application. We will install the update now, after which we will save all of your in-progress data and restart your application.");
BeginUpdate();
}
}
}
private void BeginUpdate()
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.UpdateCompleted += new AsyncCompletedEventHandler(ad_UpdateCompleted);
// Indicate progress in the application's status bar.
ad.UpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_UpdateProgressChanged);
ad.UpdateAsync();
}
void ad_UpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
{
String progressText = String.Format("{0:D}K out of {1:D}K downloaded - {2:D}% complete", e.BytesCompleted / 1024, e.BytesTotal / 1024, e.ProgressPercentage);
downloadStatus.Text = progressText;
}
void ad_UpdateCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("The update of the application's latest version was cancelled.");
return;
}
else if (e.Error != null)
{
MessageBox.Show("ERROR: Could not install the latest version of the application. Reason: \n" + e.Error.Message + "\nPlease report this error to the system administrator.");
return;
}
DialogResult dr = MessageBox.Show("The application has been updated. Restart? (If you do not restart now, the new version will not take effect until after you quit and launch the application again.)", "Restart Application", MessageBoxButtons.OKCancel);
if (DialogResult.OK == dr)
{
Application.Restart();
}
}
Private sizeOfUpdate As Long = 0
Dim WithEvents ADUpdateAsync As ApplicationDeployment
Private Sub UpdateApplication()
If (ApplicationDeployment.IsNetworkDeployed) Then
ADUpdateAsync = ApplicationDeployment.CurrentDeployment
ADUpdateAsync.CheckForUpdateAsync()
End If
End Sub
Private Sub ADUpdateAsync_CheckForUpdateProgressChanged(ByVal sender As Object, ByVal e As DeploymentProgressChangedEventArgs) Handles ADUpdateAsync.CheckForUpdateProgressChanged
DownloadStatus.Text = [String].Format("{0:D}K of {1:D}K downloaded.", e.BytesCompleted / 1024, e.BytesTotal / 1024)
End Sub
Private Sub ADUpdateAsync_CheckForUpdateCompleted(ByVal sender As Object, ByVal e As CheckForUpdateCompletedEventArgs) Handles ADUpdateAsync.CheckForUpdateCompleted
If (e.Error IsNot Nothing) Then
MessageBox.Show(("ERROR: Could not retrieve new version of the application. Reason: " + ControlChars.Lf + e.Error.Message + ControlChars.Lf + "Please report this error to the system administrator."))
Return
Else
If (e.Cancelled = True) Then
MessageBox.Show("The update was cancelled.")
End If
End If
' Ask the user if they would like to update the application now.
If (e.UpdateAvailable) Then
sizeOfUpdate = e.UpdateSizeBytes
If (Not e.IsUpdateRequired) Then
Dim dr As DialogResult = MessageBox.Show("An update is available. Would you like to update the application now?", "Update Available", MessageBoxButtons.OKCancel)
If (System.Windows.Forms.DialogResult.OK = dr) Then
BeginUpdate()
End If
Else
MessageBox.Show("A mandatory update is available for your application. We will install the update now, after which we will save all of your in-progress data and restart your application.")
BeginUpdate()
End If
End If
End Sub
Private Sub BeginUpdate()
ADUpdateAsync = ApplicationDeployment.CurrentDeployment
ADUpdateAsync.UpdateAsync()
End Sub
Private Sub ADUpdateAsync_UpdateProgressChanged(ByVal sender As Object, ByVal e As DeploymentProgressChangedEventArgs) Handles ADUpdateAsync.UpdateProgressChanged
Dim progressText As String = String.Format("{0:D}K out of {1:D}K downloaded - {2:D}% complete", e.BytesCompleted / 1024, e.BytesTotal / 1024, e.ProgressPercentage)
DownloadStatus.Text = progressText
End Sub
Private Sub ADUpdateAsync_UpdateCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs) Handles ADUpdateAsync.UpdateCompleted
If (e.Cancelled) Then
MessageBox.Show("The update of the application's latest version was cancelled.")
Exit Sub
Else
If (e.Error IsNot Nothing) Then
MessageBox.Show("ERROR: Could not install the latest version of the application. Reason: " + ControlChars.Lf + e.Error.Message + ControlChars.Lf + "Please report this error to the system administrator.")
Exit Sub
End If
End If
Dim dr As DialogResult = MessageBox.Show("The application has been updated. Restart? (If you do not restart now, the new version will not take effect until after you quit and launch the application again.)", "Restart Application", MessageBoxButtons.OKCancel)
If (dr = System.Windows.Forms.DialogResult.OK) Then
Application.Restart()
End If
End Sub
Remarks
You can configure your ClickOnce application to check for updates and install them automatically through the subscription
element of the deployment manifest. Some applications, however, need finer control over their updates. You may want to install required updates programmatically, and prompt users to install optional updates at their convenience. By turning off subscription updates in the deployment manifest, you can take complete control of your application's update policies. Alternatively, you can use automatic subscription in conjunction with ApplicationDeployment, which enables ClickOnce to update the application periodically, but uses ApplicationDeployment to download critical updates shortly after they are released.
You can test whether your deployment has an available update by using either the CheckForUpdate or the CheckForUpdateAsync method; the latter method raises the CheckForUpdateCompleted event on successful completion. CheckForDetailedUpdate returns important information about the update, such as its version number and whether it is a required update for current users. If an update is available, you can install it by using Update or UpdateAsync; the latter method raises the UpdateCompleted event after installation of the update is complete. For large updates, you can receive progress notifications through the CheckForUpdateProgressChanged and UpdateProgressChanged events, and use the information in ProgressChangedEventArgs to notify the user of the download status.
You can also use ApplicationDeployment to download large files and assemblies on demand. These files must be marked as "optional" within the deployment's application manifest so that they are not downloaded during installation. You can download the files at any point during the application's duration by using the DownloadFileGroup or the DownloadFileGroupAsync method. You can download assemblies before they are loaded into memory by supplying an event handler for the AssemblyResolve event on the AppDomain class. For more information, see Walkthrough: Downloading Assemblies on Demand with the ClickOnce Deployment API Using the Designer.
Note
If you update a ClickOnce application while the application is running, the user will not see the updates until you call the Restart method of the Application, which will close the current running instance of the application and immediately restart it.
ApplicationDeployment has no public constructor; you obtain instances of the class within a ClickOnce application through the CurrentDeployment property. You use the IsNetworkDeployed property to verify that the current application is a ClickOnce application.
ApplicationDeployment supports checking for updates and downloading updated files asynchronously by using the new Event-based Asynchronous Pattern Overview, which exposes completion callbacks as class events. ApplicationDeployment starts and manages the threads for you, and calls your application back on the correct UI thread. Through this class, you can update without locking up the application, so that the user can continue working while the update installs. If the user must stop all work while an update takes place, consider using the synchronous methods instead.
Note
Performing asynchronous updates requires that your application import both the System.Deployment.Application and System.ComponentModel namespaces.
Properties
ActivationUri |
Gets the URL used to launch the deployment manifest of the application. |
CurrentDeployment |
Returns the current ApplicationDeployment for this deployment. |
CurrentVersion |
Gets the version of the deployment for the current running instance of the application. |
DataDirectory |
Gets the path to the ClickOnce data directory. |
IsFirstRun |
Gets a value indicating whether this is the first time this application has run on the client computer. |
IsNetworkDeployed |
Gets a value indicating whether the current application is a ClickOnce application. |
TimeOfLastUpdateCheck |
Gets the date and the time ClickOnce last checked for an application update. |
UpdatedApplicationFullName |
Gets the full name of the application after it has been updated. |
UpdatedVersion |
Gets the version of the update that was recently downloaded. |
UpdateLocation |
Gets the Web site or file share from which this application updates itself. |
Methods
CheckForDetailedUpdate() |
Performs the same operation as CheckForUpdate(), but returns extended information about the available update. |
CheckForDetailedUpdate(Boolean) |
Performs the same operation as CheckForUpdate(), but returns extended information about the available update. |
CheckForUpdate() |
Checks UpdateLocation to determine whether a new update is available. |
CheckForUpdate(Boolean) |
Checks UpdateLocation to determine whether a new update is available. |
CheckForUpdateAsync() |
Checks UpdateLocation asynchronously to determine whether a new update is available. |
CheckForUpdateAsyncCancel() |
Cancels the asynchronous update check. |
DownloadFileGroup(String) |
Downloads a set of optional files on demand. |
DownloadFileGroupAsync(String) |
Downloads, on demand, a set of optional files in the background. |
DownloadFileGroupAsync(String, Object) |
Downloads, on demand, a set of optional files in the background, and passes a piece of application state to the event callbacks. |
DownloadFileGroupAsyncCancel(String) |
Cancels an asynchronous file download. |
IsFileGroupDownloaded(String) |
Checks whether the named file group has already been downloaded to the client computer. |
Update() |
Starts a synchronous download and installation of the latest version of this application. |
UpdateAsync() |
Starts an asynchronous download and installation of the latest version of this application. |
UpdateAsyncCancel() |
Cancels an asynchronous update initiated by UpdateAsync(). |
Events
CheckForUpdateCompleted |
Occurs when CheckForUpdateAsync() has completed. |
CheckForUpdateProgressChanged |
Occurs when a progress update is available on a CheckForUpdateAsync() call. |
DownloadFileGroupCompleted |
Occurs on the main application thread when a file download is complete. |
DownloadFileGroupProgressChanged |
Occurs when status information is available on a file download operation initiated by a call to DownloadFileGroupAsync. |
UpdateCompleted |
Occurs when ClickOnce has finished upgrading the application as the result of a call to UpdateAsync(). |
UpdateProgressChanged |
Occurs when ClickOnce has new status information for an update operation initiated by calling the UpdateAsync() method. |