在不增加版本号的情况下更新 ClickOnce 应用程序

Updating a ClickOnce application without bumping the version number

我有一个 ClickOnce 应用程序分布在澳大利亚的各个州,根据本地计算机的不同,会出现错误。我需要找到一些方法来更新用户,而无需远程访问他们的计算机并手动换出 dll。曾有的想法包括欺骗 ClickOnce 认为当前版本是旧版本,以强制更新一台计算机。

这样做的原因是为了不影响其他用户的更新不会影响他们,因为协调位置是一项艰巨的任务。

--进度更新--

为了欺骗 ClickOnce,我发现了 4 个包含产品版本号的文件、3 个 cdf-ms 文件和 1 个清单。如果更改版本号,两个 cdf-ms 文件(都在应用程序的清单目录中)可能会破坏应用程序,这对我来说似乎很有希望。

它们都有字符串 "%publicKeyToken%" 一串字符,然后是版本号。两者的字符串开头相同,一个以 "typewin32%%%" 结束,而另一个以 "version%" 结束。我想我走在了死胡同里,但这是一回事。

在 "version" 之后更改版本号会出现以下错误:

Problem signature:
 Problem Event Name:    CLR20r3
 Problem Signature 01:  RecordConnect.exe
 Problem Signature 02:  1.0.0.0
 Problem Signature 03:  56caca4f
 Problem Signature 04:  mscorlib
 Problem Signature 05:  4.0.30319.34209
 Problem Signature 06:  534894cc
 Problem Signature 07:  7e6
 Problem Signature 08:  0
 Problem Signature 09:  System.ArgumentException
 OS Version:    6.1.7601.2.1.0.256.48
 Locale ID: 3081
 Additional Information 1:  0a9e
 Additional Information 2:  0a9e372d3b4ad19135b953a78882e789
 Additional Information 3:  0a9e
 Additional Information 4:  0a9e372d3b4ad19135b953a78882e789

在 "typewin32" 之后更改版本号会出现以下错误:

Following errors were detected during this operation.
    * [30/08/2016 12:20:29 PM] System.Runtime.InteropServices.COMException
        - The referenced assembly is not installed on your system. (Exception from HRESULT: 0x800736B3)
        - Source: mscorlib
        - Stack trace: 
            at System.Deployment.Internal.Isolation.IsolationInterop.CreateActContext(CreateActContextParameters& Params)
            at System.Deployment.Internal.Isolation.IsolationInterop.CreateActContext(IDefinitionAppId AppId)
            at System.ActivationContext.CreateFromName(ApplicationIdentity applicationIdentity)
            at System.ActivationContext.CreatePartialActivationContext(ApplicationIdentity identity)
            at System.Deployment.Application.ApplicationActivator.Activate(DefinitionAppId appId, AssemblyManifest appManifest, String activationParameter, Boolean useActivationParameter)
            at System.Deployment.Application.ApplicationActivator.ProcessOrFollowShortcut(String shortcutFile, String& errorPageUrl, TempFile& deployFile)
            at System.Deployment.Application.ApplicationActivator.PerformDeploymentActivation(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl)
            at System.Deployment.Application.ApplicationActivator.ActivateDeploymentWorker(Object state)

--进度更新--

找到注册表。

HKEY_CLASSES_ROOT\Software\Microsoft\CurrentVersion\Deployment\SideBySide.0

里面有一大堆可以存放版本号的地方。看起来大约有 20 个包含版本号的注册表项。大多数更改都是无害的,一个会破坏系统,一个实际上会触发更新提示。可惜更新提示还没有真正更新。

--进度更新--

在注册表中进行更多操作,保存一个 .reg 文件以使生活更轻松。 .reg 更新了 ComponentStore_RandomString 值并触发了重新安装。不完全是想要的,但它是东西。

我认为试图欺骗 ClickOnce 的方法将是一个痛苦且容易出错的过程。对于我见过的大多数 ClickOnce 部署,我会倾向于此处的最低要求版本设置。您可以使用所需的最低版本(在 visual studio 中,转到 project properties > publish tab > Updates... button)以允许用户继续 运行 您的应用程序的旧版本,即使您推出了较新的版本。在您的情况下,将最低要求版本设置为适用于大多数人的当前版本似乎非常理想,然后为所有人推出补丁。遇到问题的客户可以使用最新版本来解决他们的问题,但没有其他人被迫更新,因为他们是最低要求的版本。他们可以随时更新,知道这不会为他们带来任何改变。

这里有一些关于使用最低要求版本的文档,因此您可以查看它是否适合您,具体请参阅需要更新 部分:https://msdn.microsoft.com/en-us/library/s22azw1e.aspx。抱歉,如果这个答案不是非常具体,那么有很多设置会影响这个,比如您是否仅在线,应用程序何时检查更新等。

更改值以欺骗 ClickOnce 认为该程序是早期版本的最初计划是愚蠢的,我建议 none 尝试这样做。 ClickOnce 是一个非常混乱的系统。但是,我发现了一种触发同版本软件更新的方法。

在注册表中,如果您遵循以下路径

HKEY_CLASSES_ROOT\Software\Microsoft\CurrentVersion\Deployment\SideBySide.0\PackageMetadata

我发现了两个名称很长的键,在我看来像是十六进制值。在这些键中,还有 3 个键的名称与我的应用程序 reco..tion 相对应。两个包含类似的扩展名,包含“0002.0001”,但最后一个只包含一个长字符串(public 密钥标记)后跟另一个,在重新安装或安装完全不同版本的软件时不会改变安装。这是初始 post 中提到的文件夹,如果它被更改就会破坏应用程序。删除后,我的软件会将其视为版本更改(因为包含该信息的元数据已被删除)并重新安装最新版本的所有内容。

我真心希望这对处于我处境的其他人有所帮助,但考虑到我在互联网上找到的大量信息,我怀疑很多人正在尝试做这个愚蠢的任务。