4

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.

Community
  • 1
  • 1
kdbanman
  • 10,161
  • 10
  • 46
  • 78
  • Did you notice "If you use Visual Studio to compile your application, **it will generate new hash signatures for all files** whenever you rebuild the entire project. In this case, all assemblies will be downloaded to the client, although only a few assemblies may have changed." [Link](https://msdn.microsoft.com/en-us/library/ms404267.aspx) – Reza Aghaei Sep 21 '15 at 23:59
  • Yes I did. Notice that the hashes are completely identical. This is true from the original directories, to the compiled `\bin` directory, to the published `.deploy` files. – kdbanman Sep 22 '15 at 00:25
  • 1
    How do you know the files are being re-downloaded? How are you confirming that? You can't go by what the download progress bar says. It always has the full size of all your files even if it only downloads one. Are you using something like Fiddler to confirm what's actually being downloaded? – codeConcussion Sep 22 '15 at 13:45
  • 1
    @codeConcussion, solved. Put that down in the form of an answer and it's yours. I was indeed relying on the download progress bar. I just used a network monitoring tool during the "download" and found that very little content was actually being downloaded. The progress bar must also show copy progress from the old clickonce directory to the new one. – kdbanman Sep 22 '15 at 15:34

1 Answers1

6

The issue is the ClickOnce progress dialog. It always shows the whole size of your application, even it only a single file is downloaded. Make sure to run a monitoring tool like Fiddler to see what actually is being transferred.

codeConcussion
  • 12,739
  • 8
  • 49
  • 62