Squirrel.Windows icon indicating copy to clipboard operation
Squirrel.Windows copied to clipboard

DeltaCompression FileNotFoundException when applying delta package

Open likemike91 opened this issue 8 years ago • 15 comments

Hi,

we are currently testing Squirrel.Windows for updating our application. Now I've received a strange exception recently where my log files show the following:

2016.11.18 06:23:42.665673 [WARN ] [PID: 13088] - There has been an error while checking for an update
System.ComponentModel.Win32Exception: The system cannot find the file specified
   bei DeltaCompressionDotNet.MsDelta.MsDeltaCompression.ApplyDelta(String deltaFilePath, String oldFilePath, String newFilePath)
   bei Squirrel.DeltaPackageBuilder.applyDiffToFile(String deltaPath, String relativeFilePath, String workingDirectory)
   bei Squirrel.DeltaPackageBuilder.<>c__DisplayClass3_1.<ApplyDeltaPackage>b__4(String file)
   bei Squirrel.EnumerableExtensions.ForEach[TSource](IEnumerable`1 source, Action`1 onNext)
   bei Squirrel.DeltaPackageBuilder.ApplyDeltaPackage(ReleasePackage basePackage, ReleasePackage deltaPackage, String outputFile)
   bei Squirrel.UpdateManager.ApplyReleasesImpl.<>c__DisplayClass8_0.<createFullPackagesFromDeltas>b__3()
   bei System.Threading.Tasks.Task`1.InnerInvoke()
   bei System.Threading.Tasks.Task.Execute()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei Squirrel.UpdateManager.ApplyReleasesImpl.<createFullPackagesFromDeltas>d__8.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei Squirrel.UpdateManager.ApplyReleasesImpl.<ApplyReleases>d__2.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei Squirrel.UpdateManager.<ApplyReleases>d__9.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

Are there any known issues?

likemike91 avatar Nov 18 '16 06:11 likemike91

Also seeing this.

In the packages folder there is: App-CurrentVersion-full.nupkg App-CurrentVersion+1.nupkg App-CurrentVersion+2-delta.nupkg.

I'm getting a file not found on App-CurrentVersion+1-delta.nupkg.

The RELEASES file on the server has the correct full and delta entries for each package, so I'm not sure what's going on there.

gkinsman avatar Nov 21 '16 01:11 gkinsman

Also having the same error. I checked the inputs of ApplyDelta and all of them exist. Don't know what could be wrong, any news on this?

gustavocalheiros avatar May 29 '17 15:05 gustavocalheiros

Unfortunately I don't have any news on this. I bypassed it by executing a full update in case of an Exception during Delta-Updating because I couldn't find the cause of the problem...

likemike91 avatar May 30 '17 05:05 likemike91

OK, on my side the problem is that there was missing an intermediate delta package between my new delta and the one that he was trying to make the diff... Unfortunatly the error given "FileNotFoundException" has not a lot to do with the real issue.

gustavocalheiros avatar May 31 '17 10:05 gustavocalheiros

@likemike91 is it an issue you are still experiencing with the latest version of Squirrel?

Thieum avatar May 03 '19 03:05 Thieum

@Thieum I have to try the latest version but that will take a while since somewhere in the past the decision has been made to fork Squirrel to adapt it for our needs. I'll keep you posted.

likemike91 avatar May 03 '19 06:05 likemike91

I am having exactly the same bug in the latest version of squirrel. Should I open a new issue? 2020-02-27 12:19:32> IEnableLogger: Failed to apply updates: System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified at DeltaCompressionDotNet.MsDelta.MsDeltaCompression.ApplyDelta(String deltaFilePath, String oldFilePath, String newFilePath) at Squirrel.DeltaPackageBuilder.applyDiffToFile(String deltaPath, String relativeFilePath, String workingDirectory) in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\DeltaPackage.cs:line 262 at Squirrel.EnumerableExtensions.ForEach[TSource](IEnumerable1 source, Action1 onNext) in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\EnumerableExtensions.cs:line 29 at Squirrel.DeltaPackageBuilder.ApplyDeltaPackage(ReleasePackage basePackage, ReleasePackage deltaPackage, String outputFile) in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\DeltaPackage.cs:line 135 at System.Threading.Tasks.Task1.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.UpdateManager.ApplyReleasesImpl.<createFullPackagesFromDeltas>d__8.MoveNext() in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\UpdateManager.ApplyReleases.cs:line 325 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.UpdateManager.ApplyReleasesImpl.<ApplyReleases>d__2.MoveNext() in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\UpdateManager.ApplyReleases.cs:line 35 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.UpdateManager.<ApplyReleases>d__9.MoveNext() in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\UpdateManager.cs:line 73 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.Utility.<LogIfThrows>d__431.MoveNext() in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\Utility.cs:line 0

D-Bullock avatar Feb 27 '20 02:02 D-Bullock

@D-Bullock no, we can keep tracking this issue here if it's still active in the latest version. @anaisbetts or @shiftkey or @robmen could drop the old-version label.

Thieum avatar Feb 27 '20 18:02 Thieum

Is there any recommended things I should do to isolate the problem? I've already attached a logger to the updater (snipped was attached above)

D-Bullock avatar Feb 27 '20 22:02 D-Bullock

@D-Bullock the best thing you could do is reproduce your issue in the test suite of the project, and pull request the failing test. But translating your use case to a test is the hard part of that.

Thieum avatar Feb 28 '20 16:02 Thieum

I'm also experimenting the same issue but only in production environment (not when debugging from VS):

System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified at DeltaCompressionDotNet.MsDelta.MsDeltaCompression.ApplyDelta(String deltaFilePath, String oldFilePath, String newFilePath) at Squirrel.DeltaPackageBuilder.applyDiffToFile(String deltaPath, String relativeFilePath, String workingDirectory) at Squirrel.EnumerableExtensions.ForEach[TSource](IEnumerable1 source, Action1 onNext) at Squirrel.DeltaPackageBuilder.ApplyDeltaPackage(ReleasePackage basePackage, ReleasePackage deltaPackage, String outputFile) at System.Threading.Tasks.Task1.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.UpdateManager.ApplyReleasesImpl.<createFullPackagesFromDeltas>d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Squirrel.UpdateManager.ApplyReleasesImpl.<ApplyReleases>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 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.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

leubac avatar Aug 17 '20 14:08 leubac

I've not been able to reproduce in a testing environment either. I've had to disable delta updates for my project.

D-Bullock avatar Aug 17 '20 22:08 D-Bullock

I've had to disable delta updates for my project.

I had the same problem and disabling delta updates works for me as well.

There is a commandline switch for squirrel to do that:

Squirrel.exe  <snip> --no-delta

8 avatar Jan 05 '21 10:01 8

EDIT: I ended up still running into this problem after going through all this, so while it seems to minimize the impact, doing this doesn't appear to resolve the issue entirely.

I ran across this problem today, and the solution for me turned out to be that the Releases files I had were incomplete due to a variety of reasons.
I should mention that we don't use the default implementation of the update mechism, but its still all routed through UpdateManager. I solved this by building a small application to regenerate the RELEASES file from the content in the directory.
I should caution that this could be a security concern, since you're asserting that the stored packages are valid and have not been tampered with.

The program was fairly simple and written in C# its execution is basically as follows.

  1. Create an enumeration for all files in the directory
  2. Use a Regex to extract the version number into a Version object and project this into a tuple with the file path.
  3. Order the enumeration by the version number in descending order.
    • Note: I elected to trim this to the most recent 20 versions.
  4. For each file...
    1. Load the File into a FileStream
    2. compute a SHA1 bytes array from the FileStream
    3. convert to a string using BitConverter.ToString(bytes).Replace("-", string.Empty)
      • This is the same setup that Releasify uses in Squirrel.
    4. output that to a file, with the right format, and the length of the bytes array returned from building the hash. $"{Hash} {file} {size}"
      • Make sure to use only the file name in the file column, absolute paths are invalid per squirrel

After I did this, I was able to test by installing a version of the application that was not updating correctly. To Install an older version:

  1. Locate nupkg file for older version
  2. Copy nupkg file into the InstallDir/Packages folder
  3. Open nupkg with windows explorer
    • (remember that nupkg's are just zip files)
  4. Make new directory for old version InstallDir/app-versionnumber
  5. extract nupkg/lib/net45 into new directory
  6. replace InstallDir/Packages/RELEASES file content with the correct line from the RELEASES file in your distribution directory for the version you acquired
  7. Move YourAssemblyName_ExecutionStub.exe from the InstallDir/app-versionnumber to the InstallDir and rename to YourAssemblyName.exe
  8. Update your shortcut's working directory to point to the old app-versionnumber folder
  9. Delete any other app-versionnumber folders in your InstallDir

PassivePicasso avatar Jan 06 '21 18:01 PassivePicasso

Also experiencing this. We're advising users to re-install.

While debugging this I was analyzing the RELEASES file and ended up producing this script to reproduce it;

https://gist.github.com/Horb/f6a003021ecd02cb4e9e9a0df30a64c0

Horb avatar Apr 26 '21 09:04 Horb