Context:
I'm using C# and Visual Studio 2015 to develop and deploy an application with ClickOnce, and I'm trying to shrink the ClickOnce update download size. ClickOnce is capable of delta-only updates:
When updating an application, ClickOnce compares the hash signatures of the files specified in the application manifest for the current application against the new version. If different, ClickOnce downloads the new version. If the signatures match, ClickOnce copies the existing file and uses it in the new version of the application. This approach prevents ClickOnce from having to download the entire application again, even if only one or two files have changed.
Problem:
I've verified that between updates of MyApp
, the hash signatures of most files do not change (on the command line using shasum
or in the actual manifest files). But ClickOnce still downloads every file on every update.
For instance, MyApp
depends upon Emgu.CV.dll
, and I just published MyApp 1.0.9.4
from within Visual Studio 2015. Here is the Emgu.CV.dll
reference from the manifest file located in the publish output location, MyApp\Application Files\MyApp_1_0_9_4\MyApp.exe.manifest
:
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Emgu.CV.dll" size="363520">
<assemblyIdentity name="Emgu.CV" version="3.0.0.2158" publicKeyToken="7281126722AB4438" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>lUb/oa0aQL6HWEhY8Juj6Mc1wChKo0owhJJ+sSfqZUs=</dsig:DigestValue>
</hash>
</dependentAssembly>
And here is the same .dll's dependency tag from a previous deployment, MyApp_1_0_9_2\MyApp.exe.manifest
:
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Emgu.CV.dll" size="363520">
<assemblyIdentity name="Emgu.CV" version="3.0.0.2158" publicKeyToken="7281126722AB4438" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>lUb/oa0aQL6HWEhY8Juj6Mc1wChKo0owhJJ+sSfqZUs=</dsig:DigestValue>
</hash>
</dependentAssembly>
They are identical. Notably, the <hash><dsig:DigestValue>
content is identical, just like all of the other ~150MB worth of dependencies declared in their respective tags between versions 1.0.9.2
and 1.0.9.4
.
Only a couple of hash values actually changed between those two manifest files. For example, the MyApp.exe
hash changed from
JryzNpD+emqeruXW7X2unRm0i58w9z9ct++Jeog40FI=
to
tF/hs87T4n9sMgoUJUmk31zAUsi7MsWXhLdKGxlR+EM=
But a ClickOnce update from 1.0.9.2
to 1.0.9.4
downloaded MyApp.exe
and Emgu.CV.dll
and every other file, changed or not!
Why is ClickOnce downloading files whose hash hasn't changed?
Research so far:
This SO question is related, but the answer isn't applicable because I'm not rebuilding the assemblies that are being redundantly downloaded, they're just being copied (as is evident from the unchanging hash signatures).
This SO question is related, but the asker simply misunderstood what "Copy if Newer" meant.
I've read this troubleshooting MSDN page, my problem doesn't appear.