使用ApplicationDeployment 类以编程方面对ClickOnce程序进行更新 【转载】

http://msdn.microsoft.com/zh-cn/library/system.deployment.application.applicationdeployment(VS.80).aspx

 

备注

可以配置 ClickOnce 应用程序通过部署清单的 subscription 元素自动检查和安装更新。但是,有些应用程序需要对其更新进行更细致的控制。您可能希望以编程的方式安装必需的更新,并提示用户在方便时安装可选的更新。通过关闭部署清单中的订阅更新,便可完全控制应用程序的更新策略。或者,可以结合 ApplicationDeployment 使用自动订阅功能,这种方法能使 ClickOnce 定期更新应用程序,但需使用 ApplicationDeployment 在关键更新发布后立即进行下载。

您可以使用 CheckForUpdateCheckForUpdateAsync 方法来测试您的部署是否已有可用更新;CheckForUpdateAsync 方法在成功完成后会引发 CheckForUpdateCompleted 事件。CheckForDetailedUpdate 将返回有关更新的重要信息,如版本号以及对当前用户而言是否为必需的更新。如果有可用的更新,则可使用 UpdateUpdateAsync 来安装更新;UpdateAsync 方法在更新安装完成后会引发 UpdateCompleted 事件。对于大型更新,可通过 CheckForUpdateProgressChangedUpdateProgressChanged 事件接收进度通知,并使用 ProgressChangedEventArgs 中的信息通知用户下载状态。

您还可以使用 ApplicationDeployment 来按需下载大型文件和程序集。必须在部署的应用程序清单中将这些文件标记为“可选”,这样在安装时就不会下载这些文件了。您可以在应用程序使用期间内的任何时间点使用 DownloadFileGroupDownloadFileGroupAsync 方法下载这些文件。通过针对 AppDomain 类提供 AssemblyResolve 事件的事件处理程序,可以在程序集被加载到内存中之前下载程序集。有关更多信息,请参见 演练:在设计器中使用 ClickOnce 部署 API 按需下载程序集

Note注意

如果在应用程序运行时更新 ClickOnce 应用程序,则只有在调用 ApplicationRestart 方法之后,用户才能看到更新。该方法首先关闭当前运行的应用程序实例,然后再立即重新启动它。

ApplicationDeployment 没有公共构造函数;需要通过 CurrentDeployment 属性获得该类在 ClickOnce 应用程序中的实例。可以使用 IsNetworkDeployed 属性来验证当前应用程序是否为 ClickOnce 应用程序。

ApplicationDeployment 支持使用新的 基于事件的异步模式概述 异步检查更新和下载已更新的文件,这种异步模式将完成回调作为类事件公开;ApplicationDeployment 启动和管理线程,并通过正确的 UI 线程回调应用程序。通过这种方式,可以在不锁定应用程序的情况下进行更新,这样用户就可以在安装更新期间继续工作。如果发生更新时要求用户必须停止所有工作,则请考虑改用同步方法进行更新。

Note注意

执行异步更新需要应用程序同时导入 System.Deployment 和 System.ComponentModel 命名空间。

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);
}

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();
    }
}
posted @ 2009-05-22 09:05  陈希章  阅读(2785)  评论(0编辑  收藏  举报