Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?

Desktop Auto-Save

Description
This function creates a desktop icon profile, makes a backup of desktop gadget settings, and stores size and positions of currently running windows (restored ones only).
I assigned the Hotkey 'Ctrl + Win + I' to this function and use that to store the desktop info any time I change something.
I have another function 'Desktop Auto-Load' which is called by a trigger and restores all that when my monitor profile changes.
Language
C#.net
Minimum Version
Created By
Christian Treffler
Contributors
-
Date Created
Dec 13, 2016
Date Last Modified
Jan 16, 2018

Scripted Function (Macro) Code

using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.Text;


// V2.05
// by: Christian Treffler
// 
// The function saves several informations about the current desktop and stores them 
// for the current monitor setup:
// - Current desktop icons in a desktop icon profile
// - desktop gadget settings in "%userprofile%\AppData\Local\DisplayFusion\SidebarSettings"
// - position of windows in restored state in "%userprofile%\AppData\Local\DisplayFusion\WindowSettings"
// The profile name is built using the resolution and Y-position info of each monitor
// except the primary monitor where the Y-Position is 0.
// The information will be used by the function 'Desktop Auto-Load' 
//
// V2.01-V2.03: Changes only in Desktop Auto-Load
//
// V2.04:
// Copy desktop gadget settings (sidebar) only when they are active
// Store in the ProgramSettings, if sidebar is active
// Store also the path to the sidebar
// 
// V2.05:
// When storing current window positions, do not delete the settings of windows which are currently not active.


public static class DisplayFusionFunction
{
	public static void Run(IntPtr windowHandle)
	{
		// Get Resolution of all Monitors and create profile name
		Rectangle[] Monitors = BFS.Monitor.GetMonitorBounds(); 
		string ProfileName = buildProfileName(Monitors);

		// Safe the desktop icon profile
		BFS.DisplayFusion.SaveDesktopIconsProfile(ProfileName);
		
        //Copy current sidebar settings to the DisplayFusion User folder using the ProfileName
        //Location of the sidebar settings
        string source = Environment.ExpandEnvironmentVariables("%userprofile%\\AppData\\Local\\Microsoft\\Windows Sidebar\\Settings.ini");
        //Location of the DisplyFusion user folder
        string destination = Environment.ExpandEnvironmentVariables("%userprofile%\\AppData\\Local\\DisplayFusion");
        bool ready2copy = false; // Copy only if destination folder exists
        
        // Are there desktop gadgets running?
        bool SideBarExists = BFS.Application.IsAppRunningByFile("*sidebar.exe");

        if (Directory.Exists(destination))  // DisplyFusion user folder found?
        {
            // Creat a subfolder if it doesn't exist, yet
            destination = destination + "\\SidebarSettings";
            ready2copy = Directory.Exists(destination);
            if (!ready2copy)
            {
                ready2copy = Directory.CreateDirectory(destination).Exists;
            }
        }

        if (SideBarExists)  // then copy the sidebar settings under profilename
        {
            if (ready2copy && File.Exists(source))  //copy, if everything is OK
            {
                destination = destination + "\\" + ProfileName + ".ini";
                File.Copy(source, destination, true);
            }
        }
         
        // read settings of restored windows 
        DesktopPrograms AllPrgrms = ReadProgramSettings(SideBarExists);
        
        // Begin V2.05
        DesktopPrograms SavedPrgrms = LoadProgramSettings(ProfileName); // Get the stored window settings
        
        if (SavedPrgrms.Prgrms.Count > 0)                       // are settings available?
        {
            foreach (string key in SavedPrgrms.Prgrms.Keys)     // for each stored window setting
            {
                if (!AllPrgrms.Prgrms.ContainsKey(key)) {       // if it's not in the newly generated list
                    AllPrgrms.AddProgram(SavedPrgrms.Prgrms[key]); 
                }
            }
        }
        // End V2.05
        
        SaveProgramSettings(AllPrgrms, ProfileName);
	}
	
	public static string buildProfileName(Rectangle[] screens)
	{
		// needs System.Text to have StringBuilder class
		
		StringBuilder pname = new StringBuilder();
		
		for (int i = 0; i < screens.Length; i++) // For each monitor
		{
			// Add monitors resolution in the format "[<Width>x<Height>, <Y>]"
			pname.Append("[");
			pname.Append(screens[i].Width);
			pname.Append("x");
			pname.Append(screens[i].Height);
			if(screens[i].X!=0 || screens[i].Y!=0) // Primary screen has coordinates [0,0]
			{
				// Add the y-coordinate, if not primary screen
				pname.Append(",");
				pname.Append(screens[i].Y);
			}
			pname.Append("]");
		}
		
		return pname.ToString();
	}
	
    public static DesktopPrograms ReadProgramSettings(bool SideBarExists /*V2.04*/)  // Get window settings
    {
        DesktopPrograms AllPrograms = new DesktopPrograms();
        AllPrograms.SideBarExists = SideBarExists;          // V2.04
        if (SideBarExists)                                  // V2.04
        {
            uint appID = BFS.Application.GetAppIDByFile("*sidebar.exe");
            AllPrograms.SideBarPath = BFS.Application.GetMainFileByAppID(appID);
        }

        foreach(IntPtr window in BFS.Window.GetVisibleWindowHandles())
		{
            if (BFS.Window.IsRestored(window) && BFS.Window.GetText(window)!="") // only for windows which are not maximized or minimized
            {
                DProgram prgrm = new DProgram();    // DProgram is the class to store a setting
                
                prgrm.ProgramClass = BFS.Window.GetClass(window);
                prgrm.Text = BFS.Window.GetText(window);
                prgrm.Rct = BFS.Window.GetBounds(window);
                prgrm.Ptr = window;

                AllPrograms.AddProgram(prgrm);      // add to list
            }
		}
 
        return AllPrograms;
     }

    public static void SaveProgramSettings(DesktopPrograms Data, string profile) // store all window settings in an xml file with the provided filename
    {
        XmlSerializer XmlSer = new XmlSerializer(typeof(DesktopPrograms));       // Provides the methods for XML-Serialization
        // will be stored in the users local DisplayFusion AppData folder:
        string path = Environment.ExpandEnvironmentVariables("%userprofile%\\AppData\\Local\\DisplayFusion\\WindowSettings\\" + profile + ".xml");
      
        bool ready2copy = false; // Copy only if destination folder exists

        try
        {
            //Location of the DisplyFusion user folder
            string destination = Environment.ExpandEnvironmentVariables("%userprofile%\\AppData\\Local\\DisplayFusion");
            if (Directory.Exists(destination))  // DisplyFusion user folder found?
            {
                // Creat a subfolder if it doesn't exist, yet
                destination = destination + "\\WindowSettings";
                ready2copy = Directory.Exists(destination);
                if (!ready2copy)
                {
                    ready2copy = Directory.CreateDirectory(destination).Exists;
                }
            }
        }
    
        catch (Exception) { }

        if (ready2copy) // if destination folder exists
        {
            FileStream DStream = new FileStream(path, FileMode.Create);     // Create the Filestream, overwrite mode

            try
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // Use this object
                ns.Add("", "");                                             // to prevent that attributes are added in the files

                XmlWriterSettings xws = new XmlWriterSettings();            // Use this object to
                xws.Indent = true;                                          // - add line feeds and indents
                xws.CloseOutput = true;                                     // - close stream after writing
                xws.Encoding = Encoding.Default;                            // - set encoding
                xws.IndentChars = "      ";                                 // - set indent depth
                xws.NewLineHandling = NewLineHandling.None;                 // - handle line feeds properly

                using (XmlWriter writer = XmlWriter.Create(DStream, xws))   // Now serialize
                {
                    XmlSer.Serialize(writer, Data, ns);
                    writer.Close();
                }
            }

            catch (Exception) { }

            finally
            {
                if (!(DStream == null)) DStream.Close();                    // Close the stream
            }       
        }
    }

    public static DesktopPrograms LoadProgramSettings(string profile)   // read window settings from an xml file with the provided filename
    {
        DesktopPrograms r = new DesktopPrograms();
        string p = Environment.ExpandEnvironmentVariables("%userprofile%\\AppData\\Local\\DisplayFusion\\WindowSettings\\" + profile + ".xml"); // Full Filename with path
        XmlSerializer XmlSer = new XmlSerializer(typeof(DesktopPrograms)); // Provides the methods for XML-Serialization

        FileStream DStream = null;
        try
        {
            if (File.Exists(p))
            {
                DStream = new FileStream(p, FileMode.Open);         // Create the Filestream
                r = (DesktopPrograms)XmlSer.Deserialize(DStream);   // and load the Data 
            }
        }

        catch (Exception) { }

        finally
        {
            if (!(DStream == null)) DStream.Close();                // Done
            if (r == null) r = new DesktopPrograms();               // V2.04
        }
        return r;
    }

    [Serializable]
    public class DProgram   // stores window settings
    {
        public string Text = "";
        public string ProgramClass = "";
        public Rectangle Rct = new Rectangle();
        
        [XmlIgnoreAttribute]    // the handle will not be stored to file
        public IntPtr Ptr = new IntPtr();
        
        public Point Loc
        {
            get
            {
                return Rct.Location;
            }
        }

        public DProgram() { } // empty constructor is needed to make the class serializable
    }

    [Serializable]
    public class DesktopPrograms     // list of window settings
    {
        public DesktopPrograms() { } // empty constructor is needed to make the class serializable

        public XMLDictionary<string, DProgram> Prgrms = new XMLDictionary<string, DProgram>();  // list of windows
        public bool SideBarExists = false;  // V2.04  
        public string SideBarPath = "";     // V2.04
 
        public void AddProgram(DProgram prgrm)  // build a key and add the window settings to the list
        {
            // the key will be built out of the windows class and name and a counter
            int i = 0;
            string keyo = prgrm.ProgramClass + prgrm.Text;
            string key = keyo + i.ToString("00");
            while (Prgrms.ContainsKey(key))
            {
                if (++i > 99) break;
                key = keyo + i.ToString("00");
            }
            if (i < 100)
            {
                Prgrms.Add(key, prgrm);
            }
        }
    }

    // ***** XMLDictionary *****
    // A Module to provide a dictionary which is serializable.
    // Purpose: e.g. ini-files
    // Paul Welter 3/5/2006
    //
    // http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx
    public class XMLDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
    {
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            bool wasEmpty = reader.IsEmptyElement;
            reader.Read();

            if (wasEmpty)
                return;

            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");

                reader.ReadStartElement("key");
                TKey key = (TKey)keySerializer.Deserialize(reader);
                reader.ReadEndElement();

                reader.ReadStartElement("value");
                TValue value = (TValue)valueSerializer.Deserialize(reader);
                reader.ReadEndElement();

                this.Add(key, value);

                reader.ReadEndElement();
                reader.MoveToContent();
            }
            reader.ReadEndElement();
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            // Addition by Christian Treffler, 6/9/2010:
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // Use this object
            ns.Add("", "");                                             // to prevent that attributes are added in the files
            // End of addition

            foreach (TKey key in this.Keys)
            {
                writer.WriteStartElement("item");

                writer.WriteStartElement("key");
                keySerializer.Serialize(writer, key, ns);       // Added ns in this call
                writer.WriteEndElement();

                writer.WriteStartElement("value");
                TValue value = this[key];
                valueSerializer.Serialize(writer, value, ns);   // Added ns in this call
                writer.WriteEndElement();

                writer.WriteEndElement();
            }
        }
    }
}