/// <summary> /// Beings downloading the most recent version of this application from the url represented by the /// <see cref="Update_SetupDownloadURL" /> constant and then raises either the <see cref="DownloadUpdateSuccessful" /> /// or <see cref="DownloadUpdateError" /> event. /// </summary> /// <remarks> /// <para> /// The download is performed by using a static <see cref="WebClient" /> object, which is used asynchronously. /// Multiple calls of this method at once can lead in a possible <see cref="NotSupportedException" />, /// because this class is not able to handle multiple update install operations at the same time. /// </para> /// <note type="implementnotes"> /// Use the static <see cref="IsDownloadingUpdate" /> property to check whether an aynchronous update download /// operation /// is already in progress before calling this method. /// </note> /// <note type="implementnotes"> /// Use the <see cref="AbortDownloadUpdate" /> method to cancel the asynchronous update download operation. Note that /// only the same instance who started the download operation can cancel it again. /// </note> /// </remarks> /// <exception cref="SecurityException"> /// Missing <see cref="FileIOPermissionAccess.PathDiscovery" /> or <see cref="FileIOPermissionAccess.Write" /> for the /// system's temporary directory. /// </exception> /// <exception cref="WebException"> /// <see cref="Update_SetupDownloadURL">Update_SetupDownloadURL Constant</see> represents an invalid address or an error /// occurred while downloading the data. /// </exception> /// <commondoc select='IDisposable/Methods/All/*' /> /// <permission cref="FileIOPermission"> /// to write to the system's temporary directory contents. Associated enumerations: /// <see cref="FileIOPermissionAccess.PathDiscovery" />, <see cref="FileIOPermissionAccess.Write" />. /// </permission> /// <seealso cref="DownloadUpdateSuccessful">DownloadUpdateSuccessful Event</seealso> /// <seealso cref="DownloadUpdateError">DownloadUpdateError Event</seealso> /// <seealso cref="IsDownloadingUpdate">IsDownloadingUpdate Property</seealso> /// <seealso cref="AbortDownloadUpdate">AbortDownloadUpdate Method</seealso> public void BeginDownloadUpdate() { if (this.IsDisposed) { throw new ObjectDisposedException("this"); } if (UpdateManager.currentUpdateDownloadWebClient != null) { return; } Path setupFilePath = Path.Concat(this.Environment.SystemTempPath, UpdateManager.Update_SetupDestFileName); UpdateManager.currentUpdateDownloadWebClient = new WebClient(); UpdateManager.currentUpdateDownloadWebClient.DownloadFileCompleted += (sender, e) => { try { if (this.IsDisposed || e.Cancelled) { return; } if (e.Error != null) { this.OnDownloadUpdateError(new ExceptionEventArgs(e.Error)); return; } if (!e.Cancelled) { // If the file size is lower than UpdateManager.Update_SetupMinSize, then it looks like we downloaded a web page // responding an error instead of the intended update file. if (new FileInfo(setupFilePath).Length < UpdateManager.Update_SetupMinSize) { this.OnDownloadUpdateError(new ExceptionEventArgs(new FileNotFoundException("The downloaded file could not be found or is invalid."))); return; } } } finally { if (UpdateManager.currentUpdateDownloadCaller == this) { if (UpdateManager.currentUpdateDownloadCaller != null) { UpdateManager.currentUpdateDownloadCaller.Dispose(); UpdateManager.currentUpdateDownloadCaller = null; } } } this.OnDownloadUpdateSucessful(); }; UpdateManager.currentUpdateDownloadWebClient.DownloadFileAsync(new Uri(UpdateManager.Update_SetupDownloadURL), setupFilePath); }
/// <summary> /// Copies an image file the selected folder of the selected /// <see cref="SynchronizedWallpaperCategory" />. /// </summary> /// <param name="imagePath"> /// <c>true</c> to overwrite an already existing image file; otherwise <c>false</c>. /// </param> /// <param name="overwriteOnExist"> /// A <see cref="bool" /> indicating whether the image file should be overwritten if it exists already. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="imagePath" /> is <c>null</c>. /// </exception> /// <exception cref="System.IO.IOException"> /// <paramref name="overwriteOnExist" /> is <c>false</c> and the file does already exist or /// an I/O error has occurred. /// </exception> /// <exception cref="InvalidOperationException"> /// The wrapped <see cref="WallpaperCategory" /> is no <see cref="SynchronizedWallpaperCategory" />. /// </exception> /// <inheritdoc cref="System.IO.File.Copy(string, string)" /> public virtual void AddSynchronizedImage(Path imagePath, bool overwriteOnExist) { if (imagePath == Path.None) { throw new ArgumentException(); } if (!this.IsSynchronizedCategory) { throw new InvalidOperationException(); } SynchronizedWallpaperCategory synchronizedCategory = (this.Category as SynchronizedWallpaperCategory); if (synchronizedCategory != null) { File.Copy(imagePath, Path.Concat(synchronizedCategory.SynchronizedDirectoryPath, imagePath.FileName), overwriteOnExist); } }
public void ApplyUpdate() { if (this.IsDisposed) { throw new ObjectDisposedException("this"); } Path setupPath = Path.Concat(this.Environment.SystemTempPath, UpdateManager.Update_SetupDestFileName); if (!File.Exists(setupPath)) { throw new FileNotFoundException(setupPath); } // We write the batch file even before the download started at all to check for errors. StreamWriter batchWriter = null; Path batchFilePath = Path.None; try { batchFilePath = Path.Concat(this.Environment.SystemTempPath, UpdateManager.Update_BatchFileName); batchWriter = new StreamWriter(batchFilePath); batchWriter.WriteLine("@echo off"); batchWriter.WriteLine("cd \"{0}\"", batchFilePath.ParentDirectory); batchWriter.WriteLine("echo Waiting for Wallpaper Mananger to close..."); // A little trick to make the batch wait for 2 seconds until Wallpaper Manager is closed. batchWriter.WriteLine("ping -n 2 127.0.0.1>NUL"); batchWriter.WriteLine("echo Uninstalling old version..."); // This uninstalls the old version. // Note: Run msiexec /? to get help to the msi parameters. batchWriter.WriteLine("msiexec /q /x {0}", AppEnvironment.AppGuid); batchWriter.WriteLine("echo Installing new version..."); // The rar self extract exe which is used for any Wallpaper Manager setup (to put the Setup.exe and Setup.msi // which is generated by the Installer Project into one file) requires the parameter -sp<Args> to "route" the // given commands to the "real" setup.exe which then "routes" em to the setup.msi. batchWriter.WriteLine("\"{0}\" -sp\"/q\"", UpdateManager.Update_SetupDestFileName); /* Removed due an error caused when the bootstrapper restarted the system and tried to re-execute the deleted files. * batchWriter.WriteLine("echo Deleting temporary files..."); * // The batch should delete itself and the setup file after the update. * batchWriter.WriteLine("del \"{0}\"", UpdateManager.Update_SetupDestFileName); * batchWriter.WriteLine("del \"{0}\"", UpdateManager.Update_BatchFileName);*/ batchWriter.WriteLine("echo Done."); batchWriter.WriteLine("ping -n 2 127.0.0.1>NUL"); } catch (Exception exception) { throw new IOException($"Failed to write batch file: {batchFilePath}", exception); } finally { batchWriter?.Dispose(); } // When at least Windows Vista, we better use runas to get administrator rights if we don't have them. if (AppEnvironment.IsWindowsVista) { Process.Start(new ProcessStartInfo() { WorkingDirectory = batchFilePath.ParentDirectory, Verb = "runas", FileName = UpdateManager.Update_BatchFileName }); } else { Process.Start(new ProcessStartInfo { WorkingDirectory = batchFilePath.ParentDirectory, FileName = "cmd", Arguments = string.Format(CultureInfo.InvariantCulture, "/C \"{0}\"", UpdateManager.Update_BatchFileName) }); } }