Squirrel / Squirrel.Windows

An installation and update framework for Windows desktop apps
MIT License
7.38k stars 1.03k forks source link

Update fails, when Application uses a different SharpCompress Library #1253

Closed iggsn closed 5 years ago

iggsn commented 6 years ago

My Application is refering to SharpCompress 0.19.1 already. When I execute the Update procedure through code, the processing/upgrade of my SharpCompress library fails. It seems to load it from the Update.exe, while it tries to merge mine.

The Update.exe includes the SharpCompress Library 0.17.1. If I replace the SharpCompress in my Application with the older version, the update process works fine.

As a workaround I can try to use the older SharpCompress library in my application too,. But I am wondering, why I end up in the exception of "wrong assembly version loaded".

ZARk-be commented 6 years ago

Having the same issue with one of my projects. Meaning that customers now can't auto-update as the dll is the wrong one now .. So i'll have to inform them to load the setup.exe file again :(

peppy commented 6 years ago

Hard fails delta patching with SharpCompress 0.21.1

29/06/2018 02:28:46: System.MissingMethodException: Method not found: 'Void SharpCompress.Compressors.BZip2.BZip2Stream..ctor(System.IO.Stream, SharpCompress.Compressors.CompressionMode, Boolean, Boolean)'.
29/06/2018 02:28:46: at Squirrel.Bsdiff.BinaryPatchUtility.Apply(Stream input, Func`1 openPatchStream, Stream output)
29/06/2018 02:28:46: at Squirrel.DeltaPackageBuilder.applyDiffToFile(String deltaPath, String relativeFilePath, String workingDirectory)
29/06/2018 02:28:46: at Squirrel.EnumerableExtensions.ForEach[TSource](IEnumerable`1 source, Action`1 onNext)
29/06/2018 02:28:46: at Squirrel.DeltaPackageBuilder.ApplyDeltaPackage(ReleasePackage basePackage, ReleasePackage deltaPackage, String outputFile)
29/06/2018 02:28:46: at System.Threading.Tasks.Task`1.InnerInvoke()
29/06/2018 02:28:46: at System.Threading.Tasks.Task.Execute()
29/06/2018 02:28:46: --- End of stack trace from previous location where exception was thrown ---
29/06/2018 02:28:46: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
29/06/2018 02:28:46: at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
29/06/2018 02:28:46: at Squirrel.UpdateManager.ApplyReleasesImpl.<createFullPackagesFromDeltas>d__8.MoveNext()
29/06/2018 02:28:46: --- End of stack trace from previous location where exception was thrown ---
29/06/2018 02:28:46: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
29/06/2018 02:28:46: at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
29/06/2018 02:28:46: at Squirrel.UpdateManager.ApplyReleasesImpl.<ApplyReleases>d__2.MoveNext()
29/06/2018 02:28:46: --- End of stack trace from previous location where exception was thrown ---
29/06/2018 02:28:46: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
29/06/2018 02:28:46: at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
29/06/2018 02:28:46: at Squirrel.UpdateManager.<ApplyReleases>d__9.MoveNext()
bddckr commented 6 years ago

Got bitten by this just now, too.

lukeskinner commented 6 years ago

I believe you can remove the delta entries from your RELEASES file around the version you changed SharpCompress and it might bypass this.

I remember hitting this a while ago and I think that fixed it. You will need to revert back to the right SharpCompress version still but at least users can hopefully do the full update still.

bddckr commented 6 years ago

Yeah full packages work fine, and removing the "broken" ones from the RELEASES file takes care of that.

The default way most people use Squirrel even takes care of this issue as UpdateManager.UpdateApp retries by only using full packages in case of any thrown exception.

This commit seems to have changed the constructor that Squirrel is calling: https://github.com/adamhathcock/sharpcompress/commit/e919c99b14b0e0e333afa91d7d55965f72edb679#diff-f2ddbcc653421ca84b8aafbbf72217ad I wonder if Squirrel's .nuspec should use

      <dependency id="SharpCompress" version="[0.17.1,0.21)" />

to enforce this or, probably better since SharpCompress has some security fixes in those later versions, Squirrel should be updated to use the latest SharpCompress.

fabsenet commented 6 years ago

is there a well-known best practice to test or avoid a broken auto-update?

R00iBaard commented 6 years ago
screen shot 2018-08-14 at 3 45 24 pm

And If I have never changed the SharpCompress lib? Using the latest version. This happens during an update. Anyone know what could be wrong?

RichardD2 commented 6 years ago

Full packages DO NOT work fine!

I have removed everything from the RELEASES file except for the latest full version. The update still fails:

System.MissingMethodException
Method not found: 'Void SharpCompress.Readers.IReaderExtensions.WriteEntryToFile(SharpCompress.Readers.IReader, System.String, SharpCompress.Readers.ExtractionOptions)'.

  at Squirrel.ReleasePackage.<>c__DisplayClass15_2.<ExtractZipForInstall>b__1()
   at Squirrel.Utility.<>c__DisplayClass8_0.<Retry>b__0()
   at Squirrel.Utility.Retry[T](Func`1 block, Int32 retries)
   at Squirrel.Utility.Retry(Action block, Int32 retries)
   at Squirrel.ReleasePackage.<>c__DisplayClass15_0.<ExtractZipForInstall>b__0()
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.UpdateManager.ApplyReleasesImpl.<>c__DisplayClass7_0.<<installPackageToAppDir>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<LogIfThrows>d__43`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Squirrel.UpdateManager.ApplyReleasesImpl.<ApplyReleases>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.UpdateManager.<ApplyReleases>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<LogIfThrows>d__43`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.EasyModeMixin.<UpdateApp>d__0.MoveNext()

I now face having to talk hundreds of customers through uninstalling and reinstalling my application because of this bug. 😡

RichardD2 commented 6 years ago

It seems the problem is worse than I thought. With the wrong version of SharpCompress referenced, the update fails after creating the folder for the new version.

As a result, when you close the application and try to launch it again, nothing happens. The launcher picks the empty folder as the latest version, and tries to launch the application from that folder. But the folder is empty, so there's nothing to launch.

I think the updater needs to have some way of flagging that an update is not completed. Perhaps it could create the folder with the "hidden" attribute set, and only remove it when the update is finished. (The launcher would obviously need to ignore hidden folders when checking for the latest version.)

bddckr commented 6 years ago

That's not what I experienced - the full package install

  1. Always worked
  2. Resulted in a usable install folder

Additionally the delta package failed, resulted in a folder but it was unused.

RichardD2 commented 6 years ago

Perhaps the behaviour changed with Squirrel 1.8? I'm definitely seeing the exception with only the full packages listed in the RELEASES file, and the update routine is creating an empty folder which prevents the application from launching the next time.

The problem appears with the following package references:

<packages>
  <package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net462" />
  <package id="Microsoft.Web.Xdt" version="2.1.2" targetFramework="net462" />
  <package id="Mono.Cecil" version="0.10.0" targetFramework="net462" />
  <package id="SharpCompress" version="0.22.0" targetFramework="net462" />
  <package id="Splat" version="4.0.2" targetFramework="net462" />
  <package id="squirrel.windows" version="1.8.0" targetFramework="net462" />
</packages>

After downgrading Mono.Cecil to 0.9.6.4, and SharpCompress to 0.18.0 - and reinstalling the application, of course! - the updates are working again.

fabsenet commented 6 years ago

I observed it the same way @RichardD2 did. It is bad :(

At least, users probably notice the app no longer works and start to contact you or search for a solution online.

I am still thinking about fixing this in a way it that it does not return. ...and maybe either squirrel should properly tighten the allowed version of the deltacompression library to what it really expects or there should be some reflection magic to work with what is there.

R00iBaard commented 6 years ago

Yay thanks @RichardD2 for the tip (regarding Cecil and SharpCompress versions). I can now update 👍

JayBeavers commented 6 years ago

+1, thank you @RichardD2 for the concise workaround steps, saved my bacon.

haxxordan commented 6 years ago

Is there a plan to fix this besides downgrading?

ghost commented 6 years ago

Hope for a soon fix too...

peppy commented 6 years ago

This is easily fixed via #1362. If that is not merged soon and you need a temporarily solution, you could consider using the fork I mention in that PR, which I am maintaining nuget packages for my own purposes.

anaisbetts commented 5 years ago

I mentioned this on the comment for the PR, but the last time we tried this it broke NuGet's garbage Zip parsing and broke a bunch of people. Unfortunately we're hamstrung by the particular zip parsing that NuGet does when it opens NuPkg files

anaisbetts commented 5 years ago

Oops, accidental close, sorry

fabsenet commented 5 years ago

okay, if updating sharpcompress breaks squirrel, could you not at least release a new version which pins down the required sharpcompress version to 0.17.1 so everyone just trying to update his project gets an error before he releases his next version? Could this be a oneliner changing https://github.com/Squirrel/Squirrel.Windows/blob/17863e1ee41dbab3eb041d486a2edb1427cc1630/src/Squirrel.nuspec#L15 ?

I went from nuspec Dependencies element docs to nuspec Version ranges and wildcards.

I think it could simply be changed to

<dependency id="SharpCompress" version="[0.17.1]" />

I am really not sure what

people. Unfortunately we're hamstrung by the particular zip parsing that NuGet does when it opens NuPkg files

really means, but could it also be a thing to work with the sharpcompress devs so they could make vnext first which is compatible (again) with nuget in some way?

At the moment, it is deeply worrying that everyone using squirrel will at some time release a new version with updated packages and break auto-updating.

mminns commented 5 years ago

This is hitting us with on Sourcetree and has currently broken our delta update.

stephenegriffin commented 5 years ago

There's an advisory on SharpCompress < 0.21 (https://github.com/adamhathcock/sharpcompress/commit/80ceb1c375fdb1b4ffba16528c99089e804ce61f), so we need to land something here. Perhaps @adamhathcock has some insight why your previous attempt to update broke against nuget's zip?

adamhathcock commented 5 years ago

Coming in completely out of context with regards to NuGet's zip parsing:

Could it be that NuGet doesn't support reading "streaming" zip files? Meaning, the size doesn't exist in the header for a zip entry but the optional tail block?

There seems to be a couple different things here.

Thieum commented 5 years ago

@shiftkey can be closed in favor of #897