/// <summary> /// Initialy uploads the application to the server /// </summary> /// <param name="app"></param> /// <param name="localPath">The path to the local .exe file of the application</param> public void InitialUpload(string appName, string localPath, List<string> bugFixes, List<string> newStuff, string ftpServer, string ftpUser, string privateKeyFile, string privateKeyPassPhrase, string pathToAppsFolder) { var app = new Application(); app.ApplicationVersion = new Version(); app.Name = appName; PublishApplication(app, localPath, bugFixes, newStuff, new List<string>(), ftpServer, ftpUser, privateKeyFile, privateKeyPassPhrase, pathToAppsFolder); }
/// <summary> /// Gets the application with the given name from the server /// </summary> /// <param name="app"></param> public Application GetApplication(string name, string rootUrl) { CoreTools.Logger.DebugFormat("Getting online application info for \"{0}\" from {1}", name, rootUrl); // Make sure that the rootUrl ends with a '/' if (!rootUrl.EndsWith("/")) rootUrl += "/"; var application = new Application() { Name = name, Files = new List<string>(), ApplicationVersion = new Version(), WebRootUrl = rootUrl }; // Create a Http client to download data using (var httpClient = new WebClient()) { // Open filelist file on the server and store it in the object var versionRegex = new Regex(@"^[vV][0-9]*\.[0-9]*\.[0-9]*"); var filesContent = new StreamReader(httpClient.OpenRead(string.Format("{0}{1}/files.txt", rootUrl, name))); while (!filesContent.EndOfStream) { var line = filesContent.ReadLine(); // If line matches version format, parse version-number of current version if (versionRegex.IsMatch(line)) { var versions = line.Substring(1).Split(new string[] {"."}, StringSplitOptions.RemoveEmptyEntries); application.ApplicationVersion = new Version(Convert.ToInt32(versions[0]), Convert.ToInt32(versions[1]), Convert.ToInt32(versions[2]), 0); } else { application.Files.Add(line); } } // Get changelog var changelogReader = new StreamReader(httpClient.OpenRead(string.Format("{0}{1}/changelog.xml", rootUrl, name))); var xmlContent = changelogReader.ReadToEnd(); application.ChangeLog = System.Xml.Linq.XDocument.Parse(xmlContent); CoreTools.Logger.DebugFormat("Online application information for \"{0}\" loaded:", name); CoreTools.Logger.DebugFormat(" - Online version: {0}", application.ApplicationVersion); return application; } }
/// <summary> /// Publishes the application to the server /// </summary> /// <param name="app"></param> /// <param name="localPath">The path to the local .exe file of the application</param> public void PublishApplication(Application app, string localPath, List<string> bugFixes, List<string> newStuff, List<string> deletedFiles, string ftpServer, string ftpUser, string privateKeyFile, string privateKeyPassPhrase, string pathToAppsFolder) { try { #region PRECONDITIONS if (!File.Exists(localPath)) throw new FileNotFoundException(string.Format("Could not find a part of the file '{0}'", localPath)); #endregion app.UpdateProgress = 0; app.PublishingStatus = "Connecting to SFTP server"; // Open SFTP connection to server using (var ftpClient = new SftpClient(ftpServer, ftpUser, new PrivateKeyFile(privateKeyFile, privateKeyPassPhrase))) { ftpClient.Connect(); var newVersion = AssemblyName.GetAssemblyName(localPath).Version; if (newVersion <= app.ApplicationVersion) throw new InvalidOperationException("You are trying to publish an older version than the one that is on the server! You have to increase the assembly version and republish!"); app.PublishingStatus = "Updating changelog"; // Create changelog entry app.AddVersionToChangelog(newVersion, bugFixes, newStuff, deletedFiles); ftpClient.UploadFile(this.GenerateStreamFromString(app.ChangeLog.ToString()), string.Format("{1}/{0}/changelog.xml", app.Name, pathToAppsFolder), true); app.PublishingStatus = "Gathering data"; // Load all files that have to get uploaded var localDirectory = Path.GetDirectoryName(localPath); var files = GetFileListRecursive(localDirectory, new List<string>(), localDirectory); app.Files = files; // Create new fileIndex with new version info at first line var filesIndexContent = string.Format("v{0}.{1}.{2}\r\n", newVersion.Major, newVersion.Minor, newVersion.Build); foreach (var file in app.Files) { filesIndexContent += file + "\r\n"; } var filePath = string.Format("{1}/{0}/files.txt", app.Name, pathToAppsFolder); ftpClient.UploadFile(GenerateStreamFromString(filesIndexContent), filePath, true, null); app.PublishingStatus = "Uploading files"; var uploadedFiles = 0; // Upload all files foreach (var file in app.Files) { app.PublishingStatus = string.Format("Downloading file {0}", file); var localFilePath = Path.Combine(localDirectory, file); var remotePath = string.Format("{2}/{0}/{1}", app.Name, file, pathToAppsFolder); ftpClient.UploadFile(File.Open(localFilePath, FileMode.Open, FileAccess.Read), remotePath, true); uploadedFiles++; app.PublishingProgress = (float)app.Files.Count / (float)uploadedFiles; } app.PublishingStatus = "Publishing finished"; } } catch { app.PublishingStatus = "Error"; throw; } }
/// <summary> /// Loads the application information from the webserver /// </summary> public void LoadApplicationData() { var updater = new SelfUpdater(); this.SelfUpdaterApp = updater.GetApplication(SelfUpdater.UPDATER_APPNAME, SelfUpdater.SUN_UPDATER_ROOTURL); }
/// <summary> /// Downloads the application files from the server and updates it local /// </summary> /// <param name="app">The application to update</param> /// <param name="localPath">The local path of the application to the executable file</param> public void UpdateApplication(Application app, string localPath, string rootUrl) { CoreTools.Logger.InfoFormat("Updating application \"{0}\" from {1} in {2}", app.Name, rootUrl, localPath); try { var localDirectory = Path.GetDirectoryName(localPath); var oldVersion = AssemblyName.GetAssemblyName(localPath).Version; // Open Http client to download files from remote server using (var httpClient = new WebClient()) { app.UpdateProgress = 0; var downloadCount = 0; // Download all files from the server foreach (var file in app.Files) { app.UpdateStatus = string.Format("Downloading file {0}", file); var localFilePath = Path.Combine(localDirectory, file.Replace("/", "\\")); httpClient.DownloadFile(string.Format("{2}/{0}/{1}", app.Name, file, rootUrl), localFilePath); downloadCount++; app.UpdateProgress = (float)downloadCount / (float)app.Files.Count; CoreTools.Logger.DebugFormat("Updated file {0}", localFilePath); } app.UpdateStatus = "Deleting unnecessary files"; // Delete all deletedFiles from all newer versions foreach (var version in app.GetAllVersionsFromChangeLog()) { if (new Version(version) > oldVersion) { // Delete all deletedFiles foreach (var deletedFile in app.GetAllDeletedFilesForVersion(new Version(version))) { var localFilePath = Path.Combine(localDirectory, deletedFile.Replace("/", "\\")); if (File.Exists(localFilePath)) { File.Delete(localFilePath); CoreTools.Logger.DebugFormat("Deleted file {0}", localFilePath); } } } } app.UpdateStatus = "Update finished"; } } catch (Exception ex) { app.UpdateStatus = "Error"; CoreTools.Logger.ErrorFormat("Error updating application \"{0}\": {1}", app.Name, ex.Message); throw ex; } }