Processing Ajax...

Title
Close Dialog

Message

Confirm
Close Dialog

Confirm
Close Dialog

Confirm
Close Dialog

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();
            }
        }
    }
}