我通过取消选中发布属性The application should check for updates
来禁用Visual Studio中的更新检查。
我的应用程序检查更新,用户必须选择拒绝更新。
问题是当用户跳过更新时,下次启动应用程序时,将再次显示默认的ClickOnce更新屏幕。
如何确保它永远不会显示默认的ClickOnce更新对话框?
我的更新代码:
private void CheckForUpdates()
{
if (!ApplicationDeployment.IsNetworkDeployed)
{
return;
}
var currentDeployment = ApplicationDeployment.CurrentDeployment;
UpdateCheckInfo info;
try
{
info = currentDeployment.CheckForDetailedUpdate();
}
catch (Exception e)
{
return;
}
if (!info.UpdateAvailable)
{
return;
}
var changelogDialog = new Changelog();
if (changelogDialog.ShowDialog() != true)
{
return;
}
currentDeployment.Update();
Exit();
}
这是我的表现:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<assemblyIdentity name="test.ccpl.Desktop.application" version="1.0.0.89" publicKeyToken="7613da056444d824" language="en-CA" processorArchitecture="x86" xmlns="urn:schemas-microsoft-com:asm.v1" />
<description asmv2:publisher="test ccpl" co.v1:suiteName="test" asmv2:product="test ccpl" xmlns="urn:schemas-microsoft-com:asm.v1" />
<deployment install="true" mapFileExtensions="true" co.v1:createDesktopShortcut="true">
<deploymentProvider codebase="https://test-test.test.ca/Installers/test.ccpl.Desktop.application" />
</deployment>
<dependency>
<dependentAssembly dependencyType="install" codebase="Application Files\test.ccpl.Desktop_1_0_0_89\test.ccpl.Desktop.exe.manifest" size="58997">
<assemblyIdentity name="test.ccpl.Desktop.exe" version="1.0.0.89" publicKeyToken="7613da056444d824" language="en-CA" processorArchitecture="x86" type="win32" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>u36JKY4n1mmu2LZC3Ea5uRLheiM=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
<framework targetVersion="4.7.2" profile="Full" supportedRuntime="4.0.30319" />
</compatibleFrameworks>
<publisherIdentity ...>
我认为你所看到的一切都是设计的。只要您调用currentDeployment.CheckForDetailedUpdate()
,clickonce就会将更新元数据存储在注册表中。在下次启动时,clickonce将始终查看此信息以查看是否存在待处理部署,如果存在,它还将确定用户是否已跳过此较新版本。如果你想要或不想,这是设计的。
但是,如果你真的想在启动时摆脱clickonce更新对话框,那么有一个丑陋的解决方案:-)更新:请参阅下面的第二个解决方法。
首先,让我们看看注册表以及一切如何工作:
HKEY_CURRENT_USER\Software\Classes\Software\Microsoft\Windows\CurrentVersion\Deployment\SideBySide\2.0\PackageMetadata\{2ec93463-b0c3-45e1-8364-327e96aea856}_{3f471841-eef2-47d6-89c0-d028f03a4ad5}\
wind..tion_a619d47505395849_
!PendingDeployment
结尾的值。调用CheckForDetailedUpdate
方法后,它应该如下所示:
您可以手动测试这些步骤,以查看是否所有内容都按预期工作。将它放在代码中应该变成类似的东西:
var changelogDialog = new Changelog();
if (changelogDialog.ShowDialog() != true)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Classes\Software\Microsoft\Windows\CurrentVersion\Deployment\SideBySide\2.0\PackageMetadata\{2ec93463-b0c3-45e1-8364-327e96aea856}_{3f471841-eef2-47d6-89c0-d028f03a4ad5}");
var subkeyName = key.GetSubKeyNames().Where(x => x.Contains("7613da056444d824")).OrderBy(x => x.Length).First();
var subkey = key.OpenSubKey(subkeyName, true);
subkey.SetValue("{2ad613da-6fdb-4671-af9e-18ab2e4df4d8}!PendingDeployment", new byte[] { 00, 00 }, RegistryValueKind.Binary);
return;
}
另一种解决方法:
您可以创建自己的“CheckForUpdate”方法,而不是调用内置函数CheckForDetailedUpdate()
。这不是什么大问题:
private CustomUpdateCheckInfo CheckForUpdate()
{
var info = new CustomUpdateCheckInfo();
var currentVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
var manifestUri = ApplicationDeployment.CurrentDeployment.UpdateLocation;
using (XmlTextReader reader = new XmlTextReader(manifestUri.AbsoluteUri))
{
var doc = XDocument.Load(reader);
var version = doc.Descendants().FirstOrDefault(n => n.Name.LocalName == "assemblyIdentity").Attribute("version").Value;
info.NewestVersion = version;
info.IsUpdateAvailable = currentVersion.ToString() != version;
}
return info;
}
它会将当前部署的版本与清单文件中的最新版本进行比较,并返回CustomUpdateCheckInfo
的实例:
public class CustomUpdateCheckInfo
{
public bool IsUpdateAvailable { get; set; }
public string NewestVersion { get; set; }
}