void PrepareStepOn(UpdateStepOn step)
        {
            switch (step)
            {
            case UpdateStepOn.Checking:

                ShowFrame(Frame.Checking);

                break;

            case UpdateStepOn.UpdateAvailable:

                ShowFrame(Frame.UpdateInfo);

                break;

            case UpdateStepOn.UpdateDownloaded:

                // set the update step pending (extracting)
                update.CurrentlyUpdating = UpdateOn.Extracting;

                needElevation = NeedElevationToUpdate();

                // show frame InstallUpdate
                ShowFrame(Frame.InstallUpdates);

                // put a checkmark next to downloaded
                panelDisplaying.UpdateItems[0].Status = UpdateItemStatus.Success;

                break;

            case UpdateStepOn.UpdateReadyToInstall:

                string updtDetailsFilename = Path.Combine(tempDirectory, "updtdetails.udt");

                // Try to load the update details file

                if (File.Exists(updtDetailsFilename))
                {
                    updtDetails = UpdateDetails.Load(updtDetailsFilename);
                }
                else
                {
                    throw new Exception("Update details file does not exist.");
                }

                // set the update step pending (closing processes & installing files, etc.)
                update.CurrentlyUpdating = UpdateOn.ClosingProcesses;

                needElevation = NeedElevationToUpdate();

                // show frame InstallUpdate
                ShowFrame(Frame.InstallUpdates);

                // put a checkmark next to downloaded
                panelDisplaying.UpdateItems[0].Status = UpdateItemStatus.Success;

                // set the "Extracting" text
                SetStepStatus(1, clientLang.Extract);

                break;

            default:
                throw new Exception("Can't restore from this automatic update state: " + step);
            }
        }
        void bw_DoWorkInstallSelfUpdate(object sender, DoWorkEventArgs e)
        {
            Exception except = null;

            try
            {
                string updtDetailsFilename = Path.Combine(OutputDirectory, "updtdetails.udt");

                if (File.Exists(updtDetailsFilename))
                {
                    UpdtDetails = UpdateDetails.Load(updtDetailsFilename);
                }

                //find self in Path.Combine(OutputDirectory, "base")
                UpdateFile updateFile = FindNewClient();

                //find and forcibly close oldClientLocation
                KillProcess(OldSelfLoc, FromAutoUpdate);

                int retriedTimes = 0;

                while (true)
                {
                    try
                    {
                        FileAttributes atr             = File.GetAttributes(OldSelfLoc);
                        bool           resetAttributes = (atr & FileAttributes.Hidden) != 0 || (atr & FileAttributes.ReadOnly) != 0 || (atr & FileAttributes.System) != 0;

                        // remove the ReadOnly & Hidden atributes temporarily
                        if (resetAttributes)
                        {
                            File.SetAttributes(OldSelfLoc, FileAttributes.Normal);
                        }

                        //transfer new client to the directory (Note: this assumes a standalone client - i.e. no dependencies)
                        File.Copy(NewSelfLoc, OldSelfLoc, true);

                        if (resetAttributes)
                        {
                            File.SetAttributes(OldSelfLoc, atr);
                        }
                    }
                    catch (IOException IOEx)
                    {
                        int HResult = Marshal.GetHRForException(IOEx);

                        // if sharing violation
                        if ((HResult & 0xFFFF) == 32)
                        {
                            // sleep for 1 second
                            Thread.Sleep(1000);

                            // stop waiting if cancelled
                            if (IsCancelled())
                            {
                                break;
                            }

                            // wait a maximum of 30 seconds
                            if (retriedTimes == 30)
                            {
                                throw;
                            }

                            // otherwise, retry file copy
                            ++retriedTimes;
                            continue;
                        }

                        throw;
                    }

                    break;
                }

                //Optimize client if necessary
                if (updateFile != null)
                {
                    NGenInstall(OldSelfLoc, updateFile);
                }
            }
            catch (Exception ex)
            {
                except = ex;
            }


            if (IsCancelled() || except != null)
            {
                // report cancellation
                bw.ReportProgress(0, new object[] { -1, -1, "Cancelling update...", ProgressStatus.None, null });

                // Delete temporary files
                if (except != null)
                {
                    // remove the entire temp directory
                    try
                    {
                        Directory.Delete(OutputDirectory, true);
                    }
                    catch { }
                }

                bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except });
            }
            else
            {
                bw.ReportProgress(0, new object[] { -1, -1, "Self update complete", ProgressStatus.Success, null });
            }
        }
        void bw_DoWorkExtractSelfUpdate(object sender, DoWorkEventArgs e)
        {
            Exception except = null;

            try
            {
                if (!Directory.Exists(OutputDirectory))
                {
                    Directory.CreateDirectory(OutputDirectory);
                }

                //extract downloaded self update
                ExtractUpdateFile();

                try
                {
                    // remove update file (it's no longer needed)
                    File.Delete(Filename);
                }
                catch { }


                string updtDetailsFilename = Path.Combine(OutputDirectory, "updtdetails.udt");

                if (File.Exists(updtDetailsFilename))
                {
                    UpdtDetails = UpdateDetails.Load(updtDetailsFilename);
                }


                // generate files from patches
                CreatewyUpdateFromPatch();


                //find self in Path.Combine(OutputDirectory, "base")
                FindNewClient();
            }
            catch (Exception ex)
            {
                except = ex;
            }

            if (IsCancelled() || except != null)
            {
                // report cancellation
                bw.ReportProgress(0, new object[] { -1, -1, "Cancelling update...", ProgressStatus.None, null });

                // Delete temporary files
                if (except != null)
                {
                    // remove the entire temp directory
                    try
                    {
                        Directory.Delete(OutputDirectory, true);
                    }
                    catch { }
                }

                bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except });
            }
            else
            {
                bw.ReportProgress(0, new object[] { -1, -1, "Self update extraction complete", ProgressStatus.Success, null });
            }
        }
        void bw_DoWorkSelfUpdate(object sender, DoWorkEventArgs e)
        {
            Exception except = null;

            try
            {
                // extract downloaded self update
                ExtractUpdateFile();

                try
                {
                    // remove update file (it's no longer needed)
                    File.Delete(Filename);
                }
                catch { }

                //find and forcibly close oldClientLocation
                KillProcess(OldSelfLoc, FromAutoUpdate);

                string updtDetailsFilename = Path.Combine(OutputDirectory, "updtdetails.udt");

                if (File.Exists(updtDetailsFilename))
                {
                    UpdtDetails = UpdateDetails.Load(updtDetailsFilename);

                    //remove the file to prevent conflicts with the regular product update
                    File.Delete(updtDetailsFilename);
                }


                // generate files from patches
                CreatewyUpdateFromPatch();


                //find self in Path.Combine(OutputDirectory, "base")
                UpdateFile updateFile = FindNewClient();

                int retriedTimes = 0;

                while (true)
                {
                    try
                    {
                        FileAttributes atr             = File.GetAttributes(OldSelfLoc);
                        bool           resetAttributes = (atr & FileAttributes.Hidden) != 0 || (atr & FileAttributes.ReadOnly) != 0 || (atr & FileAttributes.System) != 0;

                        // remove the ReadOnly & Hidden atributes temporarily
                        if (resetAttributes)
                        {
                            File.SetAttributes(OldSelfLoc, FileAttributes.Normal);
                        }

                        //transfer new client to the directory (Note: this assumes a standalone wyUpdate - i.e. no dependencies)
                        File.Copy(NewSelfLoc, OldSelfLoc, true);

                        if (resetAttributes)
                        {
                            File.SetAttributes(OldSelfLoc, atr);
                        }
                    }
                    catch (IOException IOEx)
                    {
                        int HResult = Marshal.GetHRForException(IOEx);

                        // if sharing violation
                        if ((HResult & 0xFFFF) == 32)
                        {
                            // sleep for 1 second
                            Thread.Sleep(1000);

                            // stop waiting if cancelled
                            if (IsCancelled())
                            {
                                break;
                            }

                            // wait a maximum of 30 seconds
                            if (retriedTimes == 30)
                            {
                                throw;
                            }

                            // otherwise, retry file copy
                            ++retriedTimes;
                            continue;
                        }

                        throw;
                    }

                    break;
                }

                // Optimize client if necessary
                if (updateFile != null)
                {
                    NGenInstall(OldSelfLoc, updateFile);
                }

                //cleanup the client update files to prevent conflicts with the product update
                File.Delete(NewSelfLoc);
                Directory.Delete(Path.Combine(OutputDirectory, "base"));
            }
            catch (Exception ex)
            {
                except = ex;
            }

            if (IsCancelled() || except != null)
            {
                // report cancellation
                bw.ReportProgress(0, new object[] { -1, -1, "Cancelling update...", ProgressStatus.None, null });

                // Delete temporary files
                if (except != null && except.GetType() != typeof(PatchApplicationException))
                {
                    // remove the entire temp directory
                    try
                    {
                        Directory.Delete(OutputDirectory, true);
                    }
                    catch { }
                }
                else
                {
                    //only 'gut' the folder leaving the server file

                    string[] dirs = Directory.GetDirectories(TempDirectory);

                    foreach (string dir in dirs)
                    {
                        try
                        {
                            Directory.Delete(dir, true);
                        }
                        catch { }
                    }
                }

                bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except });
            }
            else
            {
                bw.ReportProgress(0, new object[] { -1, -1, "Self update complete", ProgressStatus.Success, null });
            }
        }
Пример #5
0
        void bw_DoWorkUnzip(object sender, DoWorkEventArgs e)
        {
            Exception except = null;

            string updtDetailsFilename = Path.Combine(TempDirectory, "updtdetails.udt");

            try
            {
                ExtractUpdateFile();

                try
                {
                    // remove update file (it's no longer needed)
                    File.Delete(Filename);
                }
                catch { }


                // Try to load the update details file
                if (File.Exists(updtDetailsFilename))
                {
                    UpdtDetails = UpdateDetails.Load(updtDetailsFilename);
                }
                else
                {
                    throw new Exception("The update details file \"updtdetails.udt\" is missing.");
                }


                if (Directory.Exists(Path.Combine(TempDirectory, "patches")))
                {
                    // patch the files
                    foreach (UpdateFile file in UpdtDetails.UpdateFiles)
                    {
                        if (file.DeltaPatchRelativePath != null)
                        {
                            if (IsCancelled())
                            {
                                break;
                            }

                            string tempFilename = Path.Combine(TempDirectory, file.RelativePath);

                            // create the directory to store the patched file
                            if (!Directory.Exists(Path.GetDirectoryName(tempFilename)))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(tempFilename));
                            }

                            while (true)
                            {
                                try
                                {
                                    using (FileStream original = File.Open(FixUpdateDetailsPaths(file.RelativePath), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                                        using (FileStream patch = File.Open(Path.Combine(TempDirectory, file.DeltaPatchRelativePath), FileMode.Open, FileAccess.Read, FileShare.Read))
                                            using (FileStream target = File.Open(tempFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                                            {
                                                VcdiffDecoder.Decode(original, patch, target, file.NewFileAdler32);
                                            }
                                }
                                catch (IOException IOEx)
                                {
                                    int HResult = Marshal.GetHRForException(IOEx);

                                    // if sharing violation
                                    if ((HResult & 0xFFFF) == 32)
                                    {
                                        // notify main window of sharing violation
                                        bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.SharingViolation, FixUpdateDetailsPaths(file.RelativePath) });

                                        // sleep for 1 second
                                        Thread.Sleep(1000);

                                        // stop waiting if cancelled
                                        if (IsCancelled())
                                        {
                                            break;
                                        }

                                        // retry file patch
                                        continue;
                                    }

                                    throw new PatchApplicationException("Patch failed to apply to this file: " + FixUpdateDetailsPaths(file.RelativePath) + "\r\n\r\nBecause that file failed to patch, and there's no \"catch-all\" update to download, the update failed to apply. The failure to patch usually happens because the file was modified from the original version. Reinstall the original version of this app.\r\n\r\n\r\nInternal error: " + IOEx.Message);
                                }
                                catch (Exception ex)
                                {
                                    throw new PatchApplicationException("Patch failed to apply to this file: " + FixUpdateDetailsPaths(file.RelativePath) + "\r\n\r\nBecause that file failed to patch, and there's no \"catch-all\" update to download, the update failed to apply. The failure to patch usually happens because the file was modified from the original version. Reinstall the original version of this app.\r\n\r\n\r\nInternal error: " + ex.Message);
                                }

                                // the 'last write time' of the patch file is really the 'lwt' of the dest. file
                                File.SetLastWriteTime(tempFilename, File.GetLastWriteTime(Path.Combine(TempDirectory, file.DeltaPatchRelativePath)));

                                break;
                            }
                        }
                    }


                    try
                    {
                        // remove the patches directory (frees up a bit of space)
                        Directory.Delete(Path.Combine(TempDirectory, "patches"), true);
                    }
                    catch { }
                }
            }
            catch (BadPasswordException ex)
            {
                except = new BadPasswordException("Could not install the encrypted update because the password did not match.");
            }
            catch (Exception ex)
            {
                except = ex;
            }

            if (IsCancelled() || except != null)
            {
                // report cancellation
                bw.ReportProgress(0, new object[] { -1, -1, "Cancelling update...", ProgressStatus.None, null });

                // Delete temporary files

                if (except != null && except.GetType() != typeof(PatchApplicationException))
                {
                    // remove the entire temp directory
                    try
                    {
                        Directory.Delete(OutputDirectory, true);
                    }
                    catch { }
                }
                else
                {
                    //only 'gut' the folder leaving the server file

                    string[] dirs = Directory.GetDirectories(TempDirectory);

                    foreach (string dir in dirs)
                    {
                        // delete everything but the self-update folder (AutoUpdate specific)
                        //Note: this code might be causing the "pyramid of death". TODO: Check.
                        if (Path.GetFileName(dir) == "selfupdate")
                        {
                            continue;
                        }

                        try
                        {
                            Directory.Delete(dir, true);
                        }
                        catch { }
                    }

                    // remove the update details
                    if (File.Exists(updtDetailsFilename))
                    {
                        File.Delete(updtDetailsFilename);
                    }
                }

                bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except });
            }
            else
            {
                bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Success, null });
            }
        }