示例#1
0
        private void ThreadWorkProc()
        {
            Exception    resultException          = null;
            UpdateAction updateAction             = UpdateAction.Undefined;
            Version      currentVersion           = null;
            bool         applicationCloseRequired = false;

            // Do the work
            try
            {
                CheckToCancel();

                UpdateApplicationManifest appManifest = GetApplicationManifest();

                CheckToCancel();

                DoStatusCallback(-1, "Determining update actions ...");
                Version existingVersion;
                updateAction   = GetUpdateAction(appManifest, out existingVersion);
                currentVersion = existingVersion;

                if (updateAction == UpdateAction.None)
                {
                    LOG.Debug("ThreadWorkProc: Exiting thread, updateAction == UpdateAction.None");
                }
                else
                {
                    CheckToCancel();
                    LOG.Debug("ThreadWorkProc: Performing {0} from version {1} to version {2}",
                              updateAction.ToString(), (existingVersion == null) ? "Unknown" :
                              existingVersion.ToString(),
                              (appManifest.CurrentDatabaseVersion == null) ? "Not specified" :
                              appManifest.CurrentDatabaseVersion.ToString());

                    if (EnumUtils.IsFlagSet(updateAction, UpdateAction.FullRefresh))
                    {
                        currentVersion = DoFullRefresh(appManifest, out applicationCloseRequired);
                    }
                    if (!applicationCloseRequired && EnumUtils.IsFlagSet(updateAction, UpdateAction.VersionUpdate))
                    {
                        currentVersion = DoVersionUpdate(appManifest, currentVersion, out applicationCloseRequired);
                    }
                }
            }
            catch (Exception e)
            {
                resultException = e;
                LOG.Error("ThreadWorkProc: Failed to run thread", e);
            }

            _isRunning = false;

            DoCompleteCallback(updateAction, currentVersion, applicationCloseRequired, resultException);
        }
示例#2
0
        protected UpdateApplicationManifest GetApplicationManifest()
        {
            LOG.Debug("GetApplicationManifest: Attempting to download application manifest");
            string statusString = "Retrieving update manifest file from server, please wait ...";

            DoStatusCallback(-1, statusString);
            byte[] manifestData = DownloadData(_manifestDownloadUrl,
                                               delegate(int percentComplete, object callbackParam)
            {
                DoStatusCallback(percentComplete, callbackParam.ToString());
                return(!_cancelUpdate);
            }, statusString
                                               );

            LOG.Debug("GetApplicationManifest: Attempting to deserialize application manifest");
            UpdateApplicationManifest appManifest = _serializationUtils.Deserialize <UpdateApplicationManifest>(manifestData);

            appManifest.CurrentDatabaseVersion    = VersionFromString(appManifest.CurrentDatabaseVersionStr);
            appManifest.LastFullUpdateVersion     = VersionFromString(appManifest.LastFullUpdateVersionStr);
            appManifest.CurrentApplicationVersion = VersionFromString(appManifest.CurrentApplicationVersionStr);
            if ((appManifest.CurrentDatabaseVersion != null) || (appManifest.LastFullUpdateVersion != null))
            {
                if ((appManifest.CurrentDatabaseVersion == null) || (appManifest.LastFullUpdateVersion == null))
                {
                    throw new InvalidDataException("Manifest file contains a unspecified database versions");
                }
                if (appManifest.CurrentDatabaseVersion < appManifest.LastFullUpdateVersion)
                {
                    throw new InvalidDataException(string.Format("Manifest file contains a current database version that is less than the last full update version: CurrentDatabaseVersion({0}) and LastFullUpdateVersion({1})",
                                                                 appManifest.CurrentDatabaseVersion.ToString(), appManifest.LastFullUpdateVersion.ToString()));
                }
                if (string.IsNullOrEmpty(appManifest.DatabaseFileDownloadUrl))
                {
                    throw new InvalidDataException("Manifest file does not contain DatabaseFileDownloadUrl");
                }
                if (string.IsNullOrEmpty(appManifest.DatabaseScriptsDownloadUrl))
                {
                    throw new InvalidDataException("Manifest file does not contain DatabaseScriptsDownloadUrl");
                }
            }
            if (appManifest.CurrentApplicationVersion != null)
            {
                if (string.IsNullOrEmpty(appManifest.ApplicationDownloadUrl))
                {
                    throw new InvalidDataException("Manifest file does not contain ApplicationDownloadUrl");
                }
            }
            LOG.Debug("GetApplicationManifest: Got application manifest: CurrentDatabaseVersion({0}) and LastFullUpdateVersion({1}) and CurrentApplicationVersion({2})",
                      (appManifest.CurrentDatabaseVersion == null) ? "Unspecified" : appManifest.CurrentDatabaseVersion.ToString(),
                      (appManifest.LastFullUpdateVersion == null) ? "Unspecified" : appManifest.LastFullUpdateVersion.ToString(),
                      (appManifest.CurrentApplicationVersion == null) ? "Unspecified" : appManifest.CurrentApplicationVersion.ToString());

            return(appManifest);
        }
        protected override Version DoFullRefresh(UpdateApplicationManifest appManifest,
                                                 out bool applicationCloseRequired)
        {
            string programParentPath = Path.GetDirectoryName(_programExeFilePath);

            if (!FileUtils.IsWritableDirectory(programParentPath))
            {
                LOG.Debug("DoFullRefresh: Cannot write to folder: {0}", programParentPath);
                throw new UnauthorizedAccessException(string.Format("Cannot write to directory \"{0}\"",
                                                                    programParentPath));
            }

            LOG.Debug("DoFullRefresh: Attempting to download updater file");
            string tempUpdaterFilePath = MakeTempFilePath();

            string statusString = string.Format("Downloading updater content for version {0}.{1}.{2} ...",
                                                appManifest.CurrentApplicationVersion.Major.ToString(),
                                                appManifest.CurrentApplicationVersion.Minor.ToString(),
                                                appManifest.CurrentApplicationVersion.Build.ToString());

            DoStatusCallback(0, statusString);

            DownloadFile(appManifest.ApplicationDownloadUrl, tempUpdaterFilePath,
                         delegate(int percentComplete, object callbackParam)
            {
                DoStatusCallback(percentComplete, callbackParam.ToString());
                return(!_cancelUpdate);
            },
                         statusString);

            try
            {
                CheckToCancel();

                DoStatusCallback(-1, "Launching updater application ...");

                tempUpdaterFilePath = FileUtils.ChangeFileExtension(tempUpdaterFilePath, ".exe");

                CheckToCancel();

                ProcessStartInfo info = new ProcessStartInfo(tempUpdaterFilePath);
                info.UseShellExecute = true;
                using (Process process = Process.Start(info))
                {
                }
                applicationCloseRequired = true;
            }
            catch (Exception)
            {
                FileUtils.SafeDeleteFile(tempUpdaterFilePath);
                throw;
            }
            return(appManifest.CurrentApplicationVersion);
        }
        protected override Version DoVersionUpdate(UpdateApplicationManifest appManifest, Version existingVersion,
                                                   out bool applicationCloseRequired)
        {
            applicationCloseRequired = false;
            string statusString = string.Format("Downloading database script updates for version {0} ...",
                                                appManifest.CurrentDatabaseVersion.ToString());

            DoStatusCallback(0, statusString);

            string scriptsDirectory =
                DownloadAllTempFiles(appManifest.DatabaseScriptsDownloadUrl,
                                     delegate(int percentComplete, object callbackParam)
            {
                DoStatusCallback(percentComplete, callbackParam.ToString());
                return(!_cancelUpdate);
            },
                                     statusString);

            try
            {
                DoStatusCallback(-1, "Performing database script updates ...");

                CheckToCancel();

                List <string> sortedScriptList = GetSortedScriptList(appManifest, scriptsDirectory,
                                                                     existingVersion);
                int i = 0;
                foreach (string scriptFile in sortedScriptList)
                {
                    Version fromVersion, toVersion;
                    GetVersionsFromScriptFileName(Path.GetFileName(scriptFile), out fromVersion, out toVersion);
                    int percentageComplete = (i++ *100) / sortedScriptList.Count;
                    DoStatusCallback(percentageComplete, "Updating database version {0} to version {1} ...", fromVersion.ToString(), toVersion.ToString());
                    ExecuteSqlCommandFileAndDelete(scriptFile, _connectionString, true, 3);
                    CheckToCancel();
                }

                DoStatusCallback(100, "Performed database version updates");

                Version currentDatabaseVersion = GetDatabaseVersion(_connectionString);
                if (currentDatabaseVersion != appManifest.CurrentDatabaseVersion)
                {
                    throw new InvalidDataException(string.Format("Version mismatch during database update: {0} vs. {1}",
                                                                 currentDatabaseVersion.ToString(),
                                                                 appManifest.CurrentDatabaseVersion.ToString()));
                }
            }
            finally
            {
                FileUtils.SafeDeleteDirectory(scriptsDirectory);
            }
            return(appManifest.CurrentDatabaseVersion);
        }
        protected override Version DoFullRefresh(UpdateApplicationManifest appManifest,
                                                 out bool applicationCloseRequired)
        {
            applicationCloseRequired = false;

            LOG.Debug("DoFullRefresh: Attempting to download database script file");
            string tempSqlFilePath = MakeTempFilePath(".sql");

            string statusString = string.Format("Downloading database content for version {0} ...",
                                                appManifest.LastFullUpdateVersion.ToString());

            DoStatusCallback(0, statusString);

            DownloadFile(appManifest.DatabaseFileDownloadUrl, tempSqlFilePath,
                         delegate(int percentComplete, object callbackParam)
            {
                DoStatusCallback(percentComplete, callbackParam.ToString());
                return(!_cancelUpdate);
            },
                         statusString);

            CheckToCancel();

            DoStatusCallback(-1, "Performing database full refresh to version {0} (please be patient) ...",
                             appManifest.LastFullUpdateVersion.ToString());

            if (DatabaseExists(_connectionString))
            {
                LOG.Debug("DoFullRefresh: Attempting to drop existing database for full refresh");
                DropDatabase(_connectionString);
            }

            LOG.Debug("DoFullRefresh: Attempting to create database for full refresh");
            CreateDatabase(_connectionString);

            LOG.Debug("DoFullRefresh: Attempting to run database script to populate database for full refresh");
            ExecuteSqlCommandFileAndDelete(tempSqlFilePath, _connectionString, true, 0);

            Version currentDatabaseVersion = GetDatabaseVersion(_connectionString);

            if (currentDatabaseVersion != appManifest.LastFullUpdateVersion)
            {
                throw new InvalidDataException(string.Format("Version mismatch during database full refresh: {0} vs. {1}",
                                                             currentDatabaseVersion.ToString(),
                                                             appManifest.LastFullUpdateVersion.ToString()));
            }

            return(appManifest.LastFullUpdateVersion);
        }
        protected override UpdateAction GetUpdateAction(UpdateApplicationManifest appManifest,
                                                        out Version existingVersion)
        {
            existingVersion = null;
            //appManifest.CurrentApplicationVersion = new Version("1.0.18");
            if (appManifest.CurrentApplicationVersion != null)
            {
                Version exeVersion = VersionFromFile(_programExeFilePath);

                if (exeVersion < appManifest.CurrentApplicationVersion)
                {
                    return(UpdateAction.FullRefresh);
                }
            }

            return(UpdateAction.None);
        }
        protected override UpdateAction GetUpdateAction(UpdateApplicationManifest appManifest,
                                                        out Version existingVersion)
        {
            existingVersion = null;
            if (appManifest.CurrentDatabaseVersion != null)
            {
                if (DatabaseExists(_connectionString))
                {
                    try
                    {
                        existingVersion = GetDatabaseVersion(_connectionString);
                    }
                    catch (Exception)
                    {
                    }
                }
                if (existingVersion == null)
                {
                    UpdateAction action = UpdateAction.FullRefresh;
                    if (appManifest.CurrentDatabaseVersion > appManifest.LastFullUpdateVersion)
                    {
                        action |= UpdateAction.VersionUpdate;
                    }
                    return(action);
                }
                if (appManifest.CurrentDatabaseVersion > existingVersion)
                {
                    UpdateAction action = UpdateAction.None;
                    if (appManifest.LastFullUpdateVersion > existingVersion)
                    {
                        action |= UpdateAction.FullRefresh;
                    }
                    if (appManifest.CurrentDatabaseVersion > appManifest.LastFullUpdateVersion)
                    {
                        action |= UpdateAction.VersionUpdate;
                    }
                    return(action);
                }
            }

            return(UpdateAction.None);
        }
示例#8
0
 protected abstract Version DoVersionUpdate(UpdateApplicationManifest appManifest, Version existingVersion,
                                            out bool applicationCloseRequired);
示例#9
0
 protected abstract Version DoFullRefresh(UpdateApplicationManifest appManifest, out bool applicationCloseRequired);
示例#10
0
 protected abstract UpdateAction GetUpdateAction(UpdateApplicationManifest appManifest,
                                                 out Version existingVersion);
示例#11
0
 protected override Version DoVersionUpdate(UpdateApplicationManifest appManifest, Version existingVersion,
                                            out bool applicationCloseRequired)
 {
     throw new NotImplementedException("DoVersionUpdate");
 }
示例#12
0
        private List <string> GetSortedScriptList(UpdateApplicationManifest appManifest, string scriptsDirectory,
                                                  Version existingDatabaseVersion)
        {
            LOG.Debug("GetSortedScriptList: Attempting to find valid script files for update");

            List <string> sortedList = new List <string>(Directory.GetFiles(scriptsDirectory, "Update_*.sql", SearchOption.TopDirectoryOnly));

            if (sortedList.Count == 0)
            {
                throw new InvalidDataException("The script update file did not contain any valid scripts");
            }
            sortedList.Sort();
            LOG.Debug("GetSortedScriptList: Extracted {0} script files from downloaded file", sortedList.Count);

            // We want to return just the list of updates to apply, so find the indexes of those files

            // Locate initial update script file
            string searchString = string.Format("UPDATE_{0}_{1}_{2}_TO_", existingDatabaseVersion.Major.ToString("D2"),
                                                existingDatabaseVersion.Minor.ToString("D2"),
                                                existingDatabaseVersion.Build.ToString("D2"));
            int startIndex = 0;

            foreach (string filePath in sortedList)
            {
                string fileName = Path.GetFileName(filePath).ToUpper();
                if (fileName.StartsWith(searchString))
                {
                    break;
                }
                ++startIndex;
            }
            if (startIndex == sortedList.Count)
            {
                throw new InvalidDataException("The script update file did not contain a valid script to update from database version " +
                                               existingDatabaseVersion.ToString());
            }

            // Locate last update file
            searchString = string.Format("_TO_{0}_{1}_{2}.SQL", appManifest.CurrentDatabaseVersion.Major.ToString("D2"),
                                         appManifest.CurrentDatabaseVersion.Minor.ToString("D2"),
                                         appManifest.CurrentDatabaseVersion.Build.ToString("D2"));
            int endIndex;

            for (endIndex = sortedList.Count - 1; endIndex >= 0; endIndex--)
            {
                string fileName = Path.GetFileName(sortedList[endIndex]).ToUpper();
                if (fileName.EndsWith(searchString))
                {
                    break;
                }
            }
            if ((endIndex < 0) || (startIndex > endIndex))
            {
                throw new InvalidDataException("The script update file did not contain a valid script to update to database version " +
                                               appManifest.CurrentDatabaseVersion.ToString());
            }
            if (endIndex < (sortedList.Count - 1))
            {
                sortedList.RemoveRange(endIndex + 1, sortedList.Count - endIndex - 1);
            }
            if (startIndex > 0)
            {
                sortedList.RemoveRange(0, startIndex);
            }
            LOG.Debug("GetSortedScriptList: Found {0} script file(s), starting with {1} and ending with {2}",
                      sortedList.Count, Path.GetFileName(sortedList[0]), Path.GetFileName(sortedList[sortedList.Count - 1]));
            return(sortedList);
        }