Squirrel.Windows
Squirrel.Windows copied to clipboard
DeltaCompression FileNotFoundException when applying delta package
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?
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.
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?
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...
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.
@likemike91 is it an issue you are still experiencing with the latest version of Squirrel?
@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.
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, Action
1 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__43
1.MoveNext() in C:\Users\ana\code\Squirrel\Squirrel.Windows\src\Squirrel\Utility.cs:line 0
@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.
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 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.
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](IEnumerable
1 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)
I've not been able to reproduce in a testing environment either. I've had to disable delta updates for my project.
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
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.
- Create an enumeration for all files in the directory
- Use a Regex to extract the version number into a Version object and project this into a tuple with the file path.
- Order the enumeration by the version number in descending order.
- Note: I elected to trim this to the most recent 20 versions.
- For each file...
- Load the File into a
FileStream
- compute a
SHA1
bytes array from theFileStream
- convert to a string using
BitConverter.ToString(bytes).Replace("-", string.Empty)
- This is the same setup that Releasify uses in Squirrel.
- 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
- Load the File into a
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:
- Locate nupkg file for older version
- Copy nupkg file into the
InstallDir/Packages
folder - Open nupkg with windows explorer
- (remember that nupkg's are just zip files)
- Make new directory for old version
InstallDir/app-versionnumber
- extract nupkg/lib/net45 into new directory
- replace
InstallDir/Packages/RELEASES
file content with the correct line from the RELEASES file in your distribution directory for the version you acquired - Move
YourAssemblyName_ExecutionStub.exe
from theInstallDir/app-versionnumber
to theInstallDir
and rename toYourAssemblyName.exe
- Update your shortcut's working directory to point to the old app-versionnumber folder
- Delete any other
app-versionnumber
folders in yourInstallDir
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