public SynchronizedWallpaperCategory(string name, Path synchronizedDirectoryPath, IEnumerable <Wallpaper> wallpapers) : base(name) { if (!Directory.Exists(synchronizedDirectoryPath)) { throw new DirectoryNotFoundException(); } if (wallpapers != null) { foreach (Wallpaper wallpaper in wallpapers) { base.InsertItem(this.Count, wallpaper); } } this.SynchronizedDirectoryPath = synchronizedDirectoryPath; // TODO: Crosslayer-Access, try to provide the application's dispatcher via the constructor somehow. this.InvokeDispatcher = Application.Current.Dispatcher; this.FileSystemWatcher = new FileSystemWatcher(); this.FileSystemWatcher.BeginInit(); this.FileSystemWatcher.Path = synchronizedDirectoryPath; this.FileSystemWatcher.IncludeSubdirectories = false; this.FileSystemWatcher.NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.DirectoryName); this.FileSystemWatcher.EnableRaisingEvents = true; this.FileSystemWatcher.Deleted += this.FileSystemWatcher_Deleted; this.FileSystemWatcher.Created += this.FileSystemWatcher_Changed; this.FileSystemWatcher.Changed += this.FileSystemWatcher_Changed; this.FileSystemWatcher.Renamed += this.FileSystemWatcher_Renamed; this.FileSystemWatcher.EndInit(); this.Resynchronize(); }
/// <summary> /// Forces a resynchronization of the containing <see cref="Wallpaper" /> objects with the physical image files on the /// users hard disk. /// </summary> /// <commondoc select='IDisposable/Methods/All/*' /> public void Resynchronize() { if (this.IsDisposed) { throw new ObjectDisposedException("this"); } string[] existingFiles = Directory.GetFiles(this.SynchronizedDirectoryPath); // Add wallpapers that are on the hard disk but not in this category. for (int i = 0; i < existingFiles.Length; i++) { Path existingPath = new Path(existingFiles[i]); if (this.IndexOfByImagePath(existingPath) == -1) { if (SynchronizedWallpaperCategory.IsImageFileExtensionSupported(existingPath)) { this.AddAsync(existingPath); } } } // Remove wallpapers which are in this category but doesn't exist on the hard disk. for (int i = this.Count - 1; i >= 0; i--) { if ((this[i].ImagePath == Path.None) || (!existingFiles.Contains(this[i].ImagePath))) { base.RemoveItem(i); } } }
/// <summary> /// Writes the configuration data in the XML-format into the given given file using serialization. /// </summary> /// <inheritdoc cref="Write(Stream)" select='remarks' /> /// <param name="filePath"> /// The <see cref="Path" /> of the XML-file to be read from. /// </param> /// <exception cref="ArgumentException"> /// <paramref name="filePath" /> is <c>Path.None</c>. /// </exception> /// <exception cref="DirectoryNotFoundException"> /// <paramref name="filePath" /> points to a file in a directory which can not be found. /// </exception> /// <exception cref="SecurityException"> /// The caller does not have the required permission. /// </exception> /// <exception cref="UnauthorizedAccessException"> /// Missing file-system related access rights to write the file located at <paramref name="filePath" />. /// </exception> /// <inheritdoc cref="Write(Stream)" select='exception[@cref="IOException"]|exception[@cref="InvalidOperationException"]' /> /// <seealso cref="Path">Path Class</seealso> public void Write(Path filePath) { if (filePath == Path.None) { throw new ArgumentException(); } using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) this.Write(fileStream); }
/// <summary> /// Creates a new <see cref="Configuration" /> instance by reading the data from a XML-file. /// </summary> /// <inheritdoc cref="Read(Stream)" select='remarks' /> /// <param name="filePath"> /// The <see cref="Path" /> of the XML-file to be read from. /// </param> /// <exception cref="ArgumentException"> /// <paramref name="filePath" /> is <c>Path.None</c>. /// </exception> /// <exception cref="FileNotFoundException"> /// <paramref name="filePath" /> points to a file which does not exist. /// </exception> /// <exception cref="DirectoryNotFoundException"> /// <paramref name="filePath" /> points to a file in a directory which can not be found. /// Like a directory on a unmapped drive. /// </exception> /// <exception cref="IOException"> /// The stream has been closed while reading. /// </exception> /// <exception cref="SecurityException"> /// The caller does not have the required permission. /// </exception> /// <exception cref="UnauthorizedAccessException"> /// Missing file-system related access rights to read from the file located at <paramref name="filePath" />. /// </exception> /// <inheritdoc cref="Read(Stream)" select='exception[@cref="XmlException"]|exception[@cref="InvalidOperationException"]' /> /// <inheritdoc cref="Read(Stream)" select='returns' /> /// <seealso cref="Path">Path Class</seealso> public static Configuration Read(Path filePath) { if (filePath == Path.None) { throw new ArgumentException(); } using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) return(Configuration.Read(fileStream)); }
/// <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> /// Creates a new <see cref="Wallpaper" /> instance and adds it to the collection. /// </summary> /// <param name="imagePath"> /// The path of the wallpaper image. /// </param> /// <remarks> /// <para> /// The wallpaper is created asynchronously by using a <see cref="BackgroundWorker" />. If two wallpapers refering to /// the same image paths are added, one of them will be automatically ignored. /// </para> /// <para> /// If the file where <paramref name="imagePath" /> is refering to is not found, no exception will be thrown. /// </para> /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="imagePath" /> is <c>null</c>. /// </exception> private void AddAsync(Path imagePath) { if (imagePath == Path.None) { throw new ArgumentException(); } BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += (sender, e) => { Path imagePathLocal = (Path)e.Argument; Wallpaper newWallpaper = new Wallpaper(imagePathLocal); using (Image wallpaperImage = Image.FromFile(imagePathLocal)) newWallpaper.ImageSize = wallpaperImage.Size; e.Result = newWallpaper; }; worker.RunWorkerCompleted += (sender, e) => { if (e.Error != null) { // We simply ignore if the file couldn't be found or is invalid / unsupported. if ((e.Error is FileNotFoundException) || (e.Error is OutOfMemoryException)) { return; } throw e.Error; } if (!e.Cancelled) { Wallpaper newWallpaperLocal = (Wallpaper)e.Result; // Make sure the item wasn't already added by another thread. if (this.IndexOfByImagePath(newWallpaperLocal.ImagePath) == -1) { base.InsertItem(this.Count, newWallpaperLocal); } } ((BackgroundWorker)sender).Dispose(); }; // By using BackgroundWorker we make sure this operation is thread safe. worker.RunWorkerAsync(imagePath); }
/// <summary> /// Determines whether the file extension of the given file path is a supported image format. /// </summary> /// <param name="filePath"> /// The path of the file. /// </param> /// <returns> /// A <see cref="bool" /> indicating whether the file extension of the specified <paramref name="filePath" /> is a /// supported image format or not. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="filePath" /> is <c>null</c>. /// </exception> private static bool IsImageFileExtensionSupported(Path filePath) { if (filePath == Path.None) { throw new ArgumentException(); } string fileNameString = filePath.FileName; if (!fileNameString.Contains('.')) { return(false); } return(SynchronizedWallpaperCategory.WallpaperFileExtensions.Contains( fileNameString.Substring(fileNameString.IndexOf('.') + 1).ToLower(CultureInfo.CurrentCulture))); }
/// <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); } }
/// <summary> /// Updates the wallpaper preview image in the preview box. /// </summary> /// <commondoc select='All/Methods/EventHandlers[@Params="Object,+EventArgs"]/*' /> private void UpdatePreviewImage(object sender, RoutedEventArgs e) { if (this.ConfigWallpaperVM.ConfigurationMode == ConfigWallpaperMode.ConfigureStaticWallpaper) { return; } Path imageFilePath = Path.None; if ((this.ConfigWallpaperVM.HasImagePath != null) && (this.ConfigWallpaperVM.HasImagePath.Value)) { if (this.ConfigWallpaperVM.ImagePath != Path.None) { imageFilePath = this.ConfigWallpaperVM.ImagePath; } else { imageFilePath = ((Wallpaper)this.ConfigWallpaperVM.WallpaperData[0]).ImagePath; } } // We can not generate a preview if the values of the wallpapers differ. if ( (this.ConfigWallpaperVM.HasImagePath != null) && (this.ConfigWallpaperVM.IsMultiscreen != null) && (this.ConfigWallpaperVM.Placement != null) && (this.ConfigWallpaperVM.HorizontalOffset != null) && (this.ConfigWallpaperVM.VerticalOffset != null) && (this.ConfigWallpaperVM.HorizontalScale != null) && (this.ConfigWallpaperVM.VerticalScale != null) && (this.ConfigWallpaperVM.Effects != null) && (this.ConfigWallpaperVM.BackgroundColor != null)) { // Create a new Wallpaper from the image of the first given Wallpaper. Wallpaper tempWallpaper = new Wallpaper(); tempWallpaper.ImagePath = imageFilePath; tempWallpaper.IsMultiscreen = this.ConfigWallpaperVM.IsMultiscreen.Value; tempWallpaper.Placement = this.ConfigWallpaperVM.Placement.Value; tempWallpaper.Offset = new Point(this.ConfigWallpaperVM.HorizontalOffset.Value, this.ConfigWallpaperVM.VerticalOffset.Value); tempWallpaper.Scale = new Point(this.ConfigWallpaperVM.HorizontalScale.Value, this.ConfigWallpaperVM.VerticalScale.Value); tempWallpaper.Effects = this.ConfigWallpaperVM.Effects.Value; tempWallpaper.BackgroundColor = this.ConfigWallpaperVM.BackgroundColor.Value; // Look if there is another worker already running. if (this.previewWorker != null && this.previewWorker.IsBusy) { this.previewWorker.CancelAsync(); } // We use a Background Worker to create the preview in another thread making the GUI Thread not block. this.previewWorker = new BackgroundWorker() { WorkerSupportsCancellation = true }; this.previewWorker.DoWork += (senderLocal, eLocal) => { var workerArgs = (object[])eLocal.Argument; Wallpaper tempWallpaperLocal = (Wallpaper)workerArgs[0]; bool isMultiscreenWallpaperLocal = (bool)workerArgs[1]; Image previewImage = null; MemoryStream previewStream = null; try { // Draw the wallpaper using the All Cloned - Builder. WallpaperBuilderBase previewBuilder = new WallpaperBuilderAllCloned(this.ScreensSettings); if (isMultiscreenWallpaperLocal) { previewImage = previewBuilder.CreateMultiscreenFromSingle(tempWallpaperLocal, 0.2f, false); } else { var wallpapersForScreen = new[] { tempWallpaperLocal }; var wallpapersByScreen = new Wallpaper[this.ScreensSettings.Count][]; for (int i = 0; i < wallpapersByScreen.Length; i++) { wallpapersByScreen[i] = wallpapersForScreen; } previewImage = previewBuilder.CreateMultiscreenFromMultiple(wallpapersByScreen, 0.2f, false); } // Convert to ImageSource. using (previewStream = new MemoryStream()) { previewImage.Save(previewStream, ImageFormat.Bmp); eLocal.Result = BitmapDecoder.Create(previewStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames[0]; } } finally { if (previewImage != null) { previewImage.Dispose(); } if (previewStream != null) { previewStream.Dispose(); } } }; this.previewWorker.RunWorkerCompleted += (senderLocal, eLocal) => { try { if (eLocal.Error != null) { throw eLocal.Error; } else { if (!eLocal.Cancelled) { this.WallpaperPreview = (ImageSource)eLocal.Result; } } } finally { ((BackgroundWorker)senderLocal).Dispose(); } }; this.previewWorker.RunWorkerAsync(new object[] { tempWallpaper, this.ConfigWallpaperVM.IsMultiscreen.Value }); } else { if (this.Resources.Contains(ConfigWallpaperWindow.NoPreviewImageResourceKey)) { ImageSource noPreviewImage = (this.Resources[ConfigWallpaperWindow.NoPreviewImageResourceKey] as ImageSource); if (noPreviewImage != null) { this.WallpaperPreview = noPreviewImage; } } } }
public SynchronizedWallpaperCategory(string name, Path synchronizedDirectoryPath) : this(name, synchronizedDirectoryPath, null) { }
// TODO: Use XmlSerializer for reading and writing the config. // TODO: Extract Read/Write functionality into a new class (and interface perhaps) /// <summary> /// Creates a new <see cref="Configuration" /> instance by reading the data from a <see cref="Stream" />. /// </summary> /// <remarks> /// This method reads Wallpaper Manager configuration files (version 1.0, 1.1 and 1.2) by using /// <see cref="XmlDocument" />. /// </remarks> /// <param name="sourceStream"> /// The source <see cref="Stream" /> to read from. /// </param> /// <returns> /// A new <see cref="Configuration" /> instance containing the read data. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="sourceStream" /> is <c>null</c>. /// </exception> /// <exception cref="IOException"> /// <paramref name="sourceStream" /> is not readable. /// </exception> /// <exception cref="XmlException"> /// There is a load or parse error in the XML-Data. /// </exception> /// <exception cref="InvalidOperationException"> /// Error while deserializing. Refer to the object returned by the <see cref="Exception.InnerException" /> property /// for details. /// </exception> /// <overloads> /// <summary> /// Creates a new <see cref="Configuration" /> instance by reading the data from a data source. /// </summary> /// <returns> /// A new <see cref="Configuration" /> instance containing the read data. /// </returns> /// </overloads> /// <seealso cref="Stream">Stream Class</seealso> public static Configuration Read(Stream sourceStream) { if (sourceStream == null) { throw new ArgumentNullException(); } if (!sourceStream.CanRead) { throw new IOException(); } XmlDocument document = new XmlDocument(); document.Load(sourceStream); if ((document.DocumentElement == null) || (document.DocumentElement.Name != Configuration.RootNodeName)) { throw new XmlException("The configuration file has an invalid root element."); } XmlAttribute versionAttribute = document.DocumentElement.Attributes["Version"]; Version configVersion; if ((versionAttribute == null) || (!Version.TryParse(versionAttribute.InnerText, out configVersion))) { throw new XmlException("The configuration file has an invalid root element."); } Configuration configuration = new Configuration(); #region <General> XmlElement generalElement = document.DocumentElement["General"]; if (generalElement == null) { throw new XmlException("The configuration file does not contain expected element 'General'."); } XmlElement element = generalElement["CycleAfterStartup"]; if (element != null) { configuration.General.CycleAfterStartup = bool.Parse(element.InnerText); } element = generalElement["TerminateAfterStartup"]; if (element != null) { configuration.General.TerminateAfterStartup = bool.Parse(element.InnerText); } element = (generalElement["MinimizeAfterStart"] ?? generalElement["MinimizeAfterStartup"]); if (element != null) { configuration.General.MinimizeAfterStartup = bool.Parse(element.InnerText); } element = generalElement["StartAutoCyclingAfterStartup"]; if (element != null) { configuration.General.StartAutocyclingAfterStartup = bool.Parse(element.InnerText); } element = generalElement["WallpaperChangeType"]; if (element != null) { configuration.General.WallpaperChangeType = (WallpaperChangeType)Enum.Parse(typeof(WallpaperChangeType), element.InnerText); } element = generalElement["AutoCycleInterval"]; if (element != null) { configuration.General.AutocycleInterval = TimeSpan.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = generalElement["LastActiveListSize"]; if (element != null) { configuration.General.LastActiveListSize = byte.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = generalElement["CycleAfterDisplaySettingsChanged"]; if (element != null) { configuration.General.CycleAfterDisplaySettingsChanged = bool.Parse(element.InnerText); } element = generalElement["MinimizeOnClose"]; if (element != null) { configuration.General.MinimizeOnClose = bool.Parse(element.InnerText); } element = generalElement["DisplayCycleTimeAsIconOverlay"]; if (element != null) { configuration.General.DisplayCycleTimeAsIconOverlay = bool.Parse(element.InnerText); } element = generalElement["WallpaperDoubleClickAction"]; if (element != null) { configuration.General.WallpaperDoubleClickAction = (WallpaperClickAction)Enum.Parse(typeof(WallpaperClickAction), element.InnerText); } element = generalElement["TrayIconSingleClickAction"]; if (element != null) { configuration.General.TrayIconSingleClickAction = (TrayIconClickAction)Enum.Parse(typeof(TrayIconClickAction), element.InnerText); } element = generalElement["TrayIconDoubleClickAction"]; if (element != null) { configuration.General.TrayIconDoubleClickAction = (TrayIconClickAction)Enum.Parse(typeof(TrayIconClickAction), element.InnerText); } #endregion #region <ScreensSettings> XmlElement screensSettingsElement = document.DocumentElement["ScreensSettings"]; if (screensSettingsElement != null) { int settingsCounter = 0; var screensSettings = new List <ScreenSettings>(); foreach (XmlElement screenSettingsElement in screensSettingsElement) { if (screenSettingsElement.Name != "ScreenSettings") { continue; } // Make sure there aren't too many screen settings in the configuration. if (settingsCounter >= Screen.AllScreens.Length) { break; } ScreenSettings screenSettings = new ScreenSettings(settingsCounter); element = screenSettingsElement["CycleRandomly"]; if (element != null) { screenSettings.CycleRandomly = bool.Parse(element.InnerText); } element = screenSettingsElement["MarginLeft"]; if (element != null) { screenSettings.Margins.Left = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = screenSettingsElement["MarginRight"]; if (element != null) { screenSettings.Margins.Right = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = screenSettingsElement["MarginTop"]; if (element != null) { screenSettings.Margins.Top = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = screenSettingsElement["MarginBottom"]; if (element != null) { screenSettings.Margins.Bottom = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } #region <OverlayTexts> XmlElement overlayTextsElement = screenSettingsElement["OverlayTexts"]; if (overlayTextsElement != null) { foreach (XmlElement overlayTextElement in overlayTextsElement) { if (overlayTextElement.Name != "OverlayText") { continue; } WallpaperTextOverlay textOverlay = new WallpaperTextOverlay(); element = overlayTextElement["Format"]; if (element != null) { textOverlay.Format = element.InnerText; } element = overlayTextElement["Position"]; if (element != null) { textOverlay.Position = (TextOverlayPosition)Enum.Parse(typeof(TextOverlayPosition), element.InnerText); } element = overlayTextElement["FontName"]; if (element != null) { textOverlay.FontName = element.InnerText; } element = overlayTextElement["FontSize"]; if (element != null) { textOverlay.FontSize = float.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = overlayTextElement["FontStyle"]; if (element != null) { textOverlay.FontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), element.InnerText); } element = overlayTextElement["ForeColor"]; if (element != null) { textOverlay.ForeColor = ColorTranslator.FromHtml(element.InnerText); } element = overlayTextElement["BorderColor"]; if (element != null) { textOverlay.BorderColor = ColorTranslator.FromHtml(element.InnerText); } element = overlayTextElement["HorizontalOffset"]; if (element != null) { textOverlay.HorizontalOffset = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } element = overlayTextElement["VerticalOffset"]; if (element != null) { textOverlay.VerticalOffset = int.Parse(element.InnerText, CultureInfo.InvariantCulture); } screenSettings.TextOverlays.Add(textOverlay); } } #endregion #region <StaticWallpaper> XmlElement staticWallpaperElement = screenSettingsElement["StaticWallpaper"]; if (staticWallpaperElement != null) { screenSettings.StaticWallpaper = (Wallpaper)Configuration.GetWallpaperDataFromXmlElement(staticWallpaperElement, typeof(Wallpaper)); } #endregion screensSettings.Add(screenSettings); settingsCounter++; } configuration.General.ScreensSettings = new ScreenSettingsCollection(screensSettings); } #endregion #region <WallpaperCategories> XmlElement wallpaperCategoriesElement = document.DocumentElement["WallpaperCategories"]; if (wallpaperCategoriesElement != null) { foreach (XmlElement wallpaperCategoryElement in wallpaperCategoriesElement) { if ( wallpaperCategoryElement.Name != "Category" && wallpaperCategoryElement.Name != "SynchronizedFolder" && wallpaperCategoryElement.Name != "WatchedCategory" /* Version 1.1 name for synchronized folders. */ ) { continue; } element = wallpaperCategoryElement["Name"]; if (element == null) { continue; } string categoryName = element.InnerText; WallpaperDefaultSettings defaultSettings = null; element = wallpaperCategoryElement["WallpaperDefaultSettings"]; if (element != null) { defaultSettings = (WallpaperDefaultSettings)Configuration.GetWallpaperDataFromXmlElement(element, typeof(WallpaperDefaultSettings)); } #region <Wallpapers> List <Wallpaper> wallpapers; XmlElement wallpapersElement = wallpaperCategoryElement["Wallpapers"]; if (wallpapersElement != null) { wallpapers = new List <Wallpaper>(wallpapersElement.ChildNodes.Count); foreach (XmlElement wallpaperElement in wallpapersElement) { if (wallpaperElement.Name != "Wallpaper") { continue; } Wallpaper wallpaper = (Wallpaper)Configuration.GetWallpaperDataFromXmlElement(wallpaperElement, typeof(Wallpaper)); wallpapers.Add(wallpaper); } } else { wallpapers = new List <Wallpaper>(0); } #endregion bool isSynchronizedFolder = ((wallpaperCategoryElement.Name == "SynchronizedFolder") || (wallpaperCategoryElement.Name == "WatchedCategory")); WallpaperCategory category; if (isSynchronizedFolder) { element = (wallpaperCategoryElement["SynchronizedFolderPath"] ?? wallpaperCategoryElement["WatchedDirectoryPath"]); if (element == null) { continue; } Path synchronizedDirPath = new Path(element.InnerText); if (!Directory.Exists(synchronizedDirPath)) { continue; } category = new SynchronizedWallpaperCategory(categoryName, synchronizedDirPath, wallpapers); } else { category = new WallpaperCategory(categoryName, wallpapers); } category.WallpaperDefaultSettings = defaultSettings; configuration.WallpaperCategories.Add(category); } } #endregion return(configuration); }
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) }); } }
/// <inheritdoc cref="SetWallpaper(Path, Nullable{WallpaperArrangement})" /> public static void SetWallpaper(Path filePath) { Desktop.SetWallpaper(filePath, null); }
/// <summary> /// Sets a new wallpaper to be shown on the Windows desktop. /// </summary> /// <remarks> /// This method was tested on Windows Vista Business and worked fine with Bitmap and Jpeg files. /// However, the API documentation says that the API function used by this method only supports /// Bitmap files so be carefully when using the method on other operating systems. /// </remarks> /// <param name="filePath">The path of the image file.</param> /// <param name="arrangement"> /// The new arrangement of the wallpaper. Set to <c>null</c> to keep the arrangement unchanged. /// </param> /// <exception cref="SecurityException"> /// Missing framework access rights to read the file specified by <see cref="filePath"/>. /// Or missing framework access rights to read or write the registry key or its values. /// Or missing Windows access rights to read or write the registry key. /// </exception> /// <exception cref="ArgumentNullException"> /// <see cref="filePath"/> is set to <c>null</c>. /// </exception> /// <exception cref="UnauthorizedAccessException"> /// Missing Windows access rights to read the registry values. /// </exception> /// <exception cref="Win32Exception"> /// The file specified by <see cref="filePath"/> doesnt exist. /// </exception> /// <inheritdoc cref="SetWallpaperPath" select='permission[@cref="RegistryPermission"]' /> /// <permission cref="FileIOPermission"> /// for reading the wallpaper file. Associated enumerations: /// <see cref="FileIOPermissionAccess.PathDiscovery">FileIOPermissionAccess.PathDiscovery</see>, /// <see cref="FileIOPermissionAccess.Read">FileIOPermissionAccess.Read</see>. /// </permission> public static void SetWallpaper(Path filePath, WallpaperArrangement?arrangement) { new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, filePath).Demand(); Desktop.SetWallpaperInternal(filePath, arrangement, true); }