作者:sotoloraboin_678 | 来源:互联网 | 2024-11-28 17:00
在尝试通过 ClickOnce 部署我的 C# 应用程序时,遇到了自动更新功能不工作的情况。具体来说,当应用程序从本地系统安装时能够正常接收更新,但如果从服务器安装,则无法检测到任何更新。
为了确保应用程序能够正确地从网络位置检查和应用更新,首先需要确认所有必要的设置都已经正确完成,这包括发布选项卡中的发布 URL 和更新路径等配置项。此外,还应在应用程序启动时启用更新检查功能。
下面是我在项目中使用的更新检查代码片段,该代码旨在处理各种可能的异常情况,如网络连接问题或部署损坏等问题,并向用户展示相应的消息提示。
private void InstallUpdateSyncWithInfo() { UpdateCheckInfo info = null; if (ApplicationDeployment.IsNetworkDeployed) { ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment; try { info = ad.CheckForDetailedUpdate(); } catch (DeploymentDownloadException dde) { MessageBox.Show("无法下载新版本的应用程序。请检查您的网络连接,稍后再试。错误信息: " + dde.Message); return; } catch (InvalidDeploymentException ide) { MessageBox.Show("无法检查应用程序的新版本。ClickOnce 部署已损坏,请重新部署应用程序后重试。错误信息: " + ide.Message); return; } catch (InvalidOperationException ioe) { MessageBox.Show("此应用程序无法更新。可能不是 ClickOnce 应用程序。错误信息: " + ioe.Message); return; } if (info.UpdateAvailable) { Boolean doUpdate = true; if (!info.IsUpdateRequired) { DialogResult dr = MessageBox.Show("有可用的更新。是否立即更新应用程序?", "更新可用", MessageBoxButtons.OKCancel); if (dr != DialogResult.OK) { doUpdate = false; } } else { MessageBox.Show("应用程序检测到必须从当前版本升级至版本 " + info.MinimumRequiredVersion.ToString() + ". 应用程序将安装更新并重启。", "更新可用", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (doUpdate) { try { ad.Update(); MessageBox.Show("应用程序已升级,即将重启。"); Application.Restart(); } catch (DeploymentDownloadException dde) { MessageBox.Show("无法安装最新版本的应用程序。请检查您的网络连接,稍后再试。错误信息: " + dde); return; } } } } else { MessageBox.Show("没有可用的更新"); } }
针对上述问题,一个可能的解决方案是修改安装/更新位置为一个目录,而非特定的 HTML 文件。此外,由于 .NET 框架中存在一个可能导致 COMException 和 InvalidOperationException 的错误,建议直接解析清单文件中的版本号并与当前程序集版本进行比较来实现更新检查功能。这种方法虽然较为基础,但在某些情况下更为可靠。
private bool CheckForUpdateAvailable() { Uri updateLocation = ApplicationDeployment.CurrentDeployment.UpdateLocation; WebClient webClient = new WebClient(); webClient.Encoding = Encoding.UTF8; string manifestFile = webClient.DownloadString(updateLocation); int startOfXml = manifestFile.IndexOf('<'); manifestFile = manifestFile.Substring(startOfXml); Version version; XmlDocument doc = new XmlDocument(); doc.LoadXml(manifestFile); XmlNodeList nodesList = doc.GetElementsByTagName("assemblyIdentity"); if (nodesList == null || nodesList.Count <= 0) { throw new XmlException("无法读取 XML 清单文件,这是检查是否有更新所必需的。"); } XmlNode theNode = nodesList[0]; version = new Version(theNode.Attributes["version"].Value); if (version > ApplicationDeployment.CurrentDeployment.CurrentVersion) { return true; } return false; }
最后,在应用程序启动时调用此方法以检查是否有可用更新,并根据结果决定是否执行更新操作。
if (ApplicationDeployment.IsNetworkDeployed) { bool updateIsAvailable; try { updateIsAvailable = CheckForUpdateAvailable(); } catch { // 处理非网络部署等情况 } if (updateIsAvailable) { var ad = ApplicationDeployment.CurrentDeployment; if (ad != null) { ad.Update(); Application.Restart(); } } }