From bcf0789aebbd1a558634074f5a7d686557ad82d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20H=C3=BCtter?= Date: Mon, 15 Apr 2019 00:29:48 +0200 Subject: [PATCH] read display infos --- DesktopRestorer/App.config | 6 +- DesktopRestorer/DesktopRestorer.csproj | 30 +- DesktopRestorer/ExternalMethods.cs | 858 ++++++++++++++++++ DesktopRestorer/FodyWeavers.xml | 4 + DesktopRestorer/FodyWeavers.xsd | 54 ++ DesktopRestorer/MainWindow.xaml | 34 +- DesktopRestorer/MainWindow.xaml.cs | 241 ++--- .../Properties/Resources.Designer.cs | 44 +- .../Properties/Settings.Designer.cs | 22 +- DesktopRestorer/packages.config | 7 + RestorerTest/Properties/AssemblyInfo.cs | 20 + RestorerTest/RestorerTest.csproj | 84 ++ RestorerTest/UnitTest1.cs | 13 + RestorerTest/packages.config | 10 + WindowRestorer.sln | 22 + 15 files changed, 1245 insertions(+), 204 deletions(-) create mode 100644 DesktopRestorer/ExternalMethods.cs create mode 100644 DesktopRestorer/FodyWeavers.xml create mode 100644 DesktopRestorer/FodyWeavers.xsd create mode 100644 DesktopRestorer/packages.config create mode 100644 RestorerTest/Properties/AssemblyInfo.cs create mode 100644 RestorerTest/RestorerTest.csproj create mode 100644 RestorerTest/UnitTest1.cs create mode 100644 RestorerTest/packages.config diff --git a/DesktopRestorer/App.config b/DesktopRestorer/App.config index 787dcbe..ecdcf8a 100644 --- a/DesktopRestorer/App.config +++ b/DesktopRestorer/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/DesktopRestorer/DesktopRestorer.csproj b/DesktopRestorer/DesktopRestorer.csproj index 8644ae5..a9190ad 100644 --- a/DesktopRestorer/DesktopRestorer.csproj +++ b/DesktopRestorer/DesktopRestorer.csproj @@ -1,5 +1,6 @@  + Debug @@ -8,12 +9,15 @@ WinExe DesktopRestorer DesktopRestorer - v4.7.1 + v4.7.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true true + + + AnyCPU @@ -37,8 +41,19 @@ true + + ..\packages\DynamicData.6.9.0.2586\lib\net46\DynamicData.dll + + + ..\packages\PropertyChanged.Fody.2.6.1\lib\net452\PropertyChanged.dll + + + ..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll + + + @@ -65,6 +80,7 @@ App.xaml Code + MainWindow.xaml Code @@ -88,6 +104,7 @@ ResXFileCodeGenerator Resources.Designer.cs + SettingsSingleFileGenerator Settings.Designer.cs @@ -96,5 +113,16 @@ + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/DesktopRestorer/ExternalMethods.cs b/DesktopRestorer/ExternalMethods.cs new file mode 100644 index 0000000..4aae8c1 --- /dev/null +++ b/DesktopRestorer/ExternalMethods.cs @@ -0,0 +1,858 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; + +namespace DesktopRestorer +{ + public static class ExternalMethods + { + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public long x; + public long y; + } + + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWPLACEMENT + { + public uint length; + public uint flags; + public uint showCmd; + public POINT ptMinPosition; + public POINT ptMaxPosition; + public RECT rcNormalPosition; + public RECT rcDevice; + } + + public enum ShowWindowCommands + { + /// + /// Hides the window and activates another window. + /// + Hide = 0, + + /// + /// Activates and displays a window. If the window is minimized or + /// maximized, the system restores it to its original size and position. + /// An application should specify this flag when displaying the window + /// for the first time. + /// + Normal = 1, + + /// + /// Activates the window and displays it as a minimized window. + /// + ShowMinimized = 2, + + /// + /// Maximizes the specified window. + /// + Maximize = 3, // is this the right value? + + /// + /// Activates the window and displays it as a maximized window. + /// + ShowMaximized = 3, + + /// + /// Displays a window in its most recent size and position. This value + /// is similar to , except + /// the window is not activated. + /// + ShowNoActivate = 4, + + /// + /// Activates the window and displays it in its current size and position. + /// + Show = 5, + + /// + /// Minimizes the specified window and activates the next top-level + /// window in the Z order. + /// + Minimize = 6, + + /// + /// Displays the window as a minimized window. This value is similar to + /// , except the + /// window is not activated. + /// + ShowMinNoActive = 7, + + /// + /// Displays the window in its current size and position. This value is + /// similar to , except the + /// window is not activated. + /// + ShowNA = 8, + + /// + /// Activates and displays the window. If the window is minimized or + /// maximized, the system restores it to its original size and position. + /// An application should specify this flag when restoring a minimized window. + /// + Restore = 9, + + /// + /// Sets the show state based on the SW_* value specified in the + /// STARTUPINFO structure passed to the CreateProcess function by the + /// program that started the application. + /// + ShowDefault = 10, + + /// + /// Windows 2000/XP: Minimizes a window, even if the thread + /// that owns the window is not responding. This flag should only be + /// used when minimizing windows from a different thread. + /// + ForceMinimize = 11 + } + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern int GetSystemMetrics(SystemMetric smIndex); + + [DllImport("user32.dll")] + internal static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, + IntPtr dwData); + + internal delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData); + + +// size of a device name string + private const int CCHDEVICENAME = 32; + + /// + /// The MONITORINFOEX structure contains information about a display monitor. + /// The GetMonitorInfo function stores information into a MONITORINFOEX structure or a MONITORINFO structure. + /// The MONITORINFOEX structure is a superset of the MONITORINFO structure. The MONITORINFOEX structure adds a string member to contain a name + /// for the display monitor. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct MONITORINFOEX + { + /// + /// The size, in bytes, of the structure. Set this member to sizeof(MONITORINFOEX) (72) before calling the GetMonitorInfo function. + /// Doing so lets the function determine the type of structure you are passing to it. + /// + public int Size; + + /// + /// A RECT structure that specifies the display monitor rectangle, expressed in virtual-screen coordinates. + /// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values. + /// + public RectStruct Monitor; + + /// + /// A RECT structure that specifies the work area rectangle of the display monitor that can be used by applications, + /// expressed in virtual-screen coordinates. Windows uses this rectangle to maximize an application on the monitor. + /// The rest of the area in rcMonitor contains system windows such as the task bar and side bars. + /// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values. + /// + public RectStruct WorkArea; + + /// + /// The attributes of the display monitor. + /// + /// This member can be the following value: + /// 1 : MONITORINFOF_PRIMARY + /// + public uint Flags; + + /// + /// A string that specifies the device name of the monitor being used. Most applications have no use for a display monitor name, + /// and so can save some bytes by using a MONITORINFO structure. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)] + public string DeviceName; + + public void Init() + { + this.Size = 40 + 2 * CCHDEVICENAME; + this.DeviceName = string.Empty; + } + } + + /// + /// The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle. + /// + /// + /// + /// By convention, the right and bottom edges of the rectangle are normally considered exclusive. + /// In other words, the pixel whose coordinates are ( right, bottom ) lies immediately outside of the the rectangle. + /// For example, when RECT is passed to the FillRect function, the rectangle is filled up to, but not including, + /// the right column and bottom row of pixels. This structure is identical to the RECTL structure. + /// + [StructLayout(LayoutKind.Sequential)] + public struct RectStruct + { + /// + /// The x-coordinate of the upper-left corner of the rectangle. + /// + public int Left; + + /// + /// The y-coordinate of the upper-left corner of the rectangle. + /// + public int Top; + + /// + /// The x-coordinate of the lower-right corner of the rectangle. + /// + public int Right; + + /// + /// The y-coordinate of the lower-right corner of the rectangle. + /// + public int Bottom; + } + + public static List EnumMonitors() + { + var mons = new List(); + + EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumCallBack, IntPtr.Zero); + + return mons; + bool MonitorEnumCallBack(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData) + { + MONITORINFOEX mon_info = new MONITORINFOEX(); + mon_info.Size = Marshal.SizeOf(mon_info); + GetMonitorInfo(hMonitor, ref mon_info); + ///Monitor info is stored in 'mon_info' + mons.Add(mon_info); + return true; + } + } + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi); + +//[DllImport("user32.dll")] +//static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); + /// + /// Flags used with the Windows API (User32.dll):GetSystemMetrics(SystemMetric smIndex) + /// + /// This Enum and declaration signature was written by Gabriel T. Sharp + /// ai_productions@verizon.net or osirisgothra@hotmail.com + /// Obtained on pinvoke.net, please contribute your code to support the wiki! + /// + public enum SystemMetric : int + { + /// + /// The flags that specify how the system arranged minimized windows. For more information, see the Remarks section in this topic. + /// + SM_ARRANGE = 56, + + /// + /// The value that specifies how the system is started: + /// 0 Normal boot + /// 1 Fail-safe boot + /// 2 Fail-safe with network boot + /// A fail-safe boot (also called SafeBoot, Safe Mode, or Clean Boot) bypasses the user startup files. + /// + SM_CLEANBOOT = 67, + + /// + /// The number of display monitors on a desktop. For more information, see the Remarks section in this topic. + /// + SM_CMONITORS = 80, + + /// + /// The number of buttons on a mouse, or zero if no mouse is installed. + /// + SM_CMOUSEBUTTONS = 43, + + /// + /// The width of a window border, in pixels. This is equivalent to the SM_CXEDGE value for windows with the 3-D look. + /// + SM_CXBORDER = 5, + + /// + /// The width of a cursor, in pixels. The system cannot create cursors of other sizes. + /// + SM_CXCURSOR = 13, + + /// + /// This value is the same as SM_CXFIXEDFRAME. + /// + SM_CXDLGFRAME = 7, + + /// + /// The width of the rectangle around the location of a first click in a double-click sequence, in pixels. , + /// The second click must occur within the rectangle that is defined by SM_CXDOUBLECLK and SM_CYDOUBLECLK for the system + /// to consider the two clicks a double-click. The two clicks must also occur within a specified time. + /// To set the width of the double-click rectangle, call SystemParametersInfo with SPI_SETDOUBLECLKWIDTH. + /// + SM_CXDOUBLECLK = 36, + + /// + /// The number of pixels on either side of a mouse-down point that the mouse pointer can move before a drag operation begins. + /// This allows the user to click and release the mouse button easily without unintentionally starting a drag operation. + /// If this value is negative, it is subtracted from the left of the mouse-down point and added to the right of it. + /// + SM_CXDRAG = 68, + + /// + /// The width of a 3-D border, in pixels. This metric is the 3-D counterpart of SM_CXBORDER. + /// + SM_CXEDGE = 45, + + /// + /// The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels. + /// SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border. + /// This value is the same as SM_CXDLGFRAME. + /// + SM_CXFIXEDFRAME = 7, + + /// + /// The width of the left and right edges of the focus rectangle that the DrawFocusRectdraws. + /// This value is in pixels. + /// Windows 2000: This value is not supported. + /// + SM_CXFOCUSBORDER = 83, + + /// + /// This value is the same as SM_CXSIZEFRAME. + /// + SM_CXFRAME = 32, + + /// + /// The width of the client area for a full-screen window on the primary display monitor, in pixels. + /// To get the coordinates of the portion of the screen that is not obscured by the system taskbar or by application desktop toolbars, + /// call the SystemParametersInfofunction with the SPI_GETWORKAREA value. + /// + SM_CXFULLSCREEN = 16, + + /// + /// The width of the arrow bitmap on a horizontal scroll bar, in pixels. + /// + SM_CXHSCROLL = 21, + + /// + /// The width of the thumb box in a horizontal scroll bar, in pixels. + /// + SM_CXHTHUMB = 10, + + /// + /// The default width of an icon, in pixels. The LoadIcon function can load only icons with the dimensions + /// that SM_CXICON and SM_CYICON specifies. + /// + SM_CXICON = 11, + + /// + /// The width of a grid cell for items in large icon view, in pixels. Each item fits into a rectangle of size + /// SM_CXICONSPACING by SM_CYICONSPACING when arranged. This value is always greater than or equal to SM_CXICON. + /// + SM_CXICONSPACING = 38, + + /// + /// The default width, in pixels, of a maximized top-level window on the primary display monitor. + /// + SM_CXMAXIMIZED = 61, + + /// + /// The default maximum width of a window that has a caption and sizing borders, in pixels. + /// This metric refers to the entire desktop. The user cannot drag the window frame to a size larger than these dimensions. + /// A window can override this value by processing the WM_GETMINMAXINFO message. + /// + SM_CXMAXTRACK = 59, + + /// + /// The width of the default menu check-mark bitmap, in pixels. + /// + SM_CXMENUCHECK = 71, + + /// + /// The width of menu bar buttons, such as the child window close button that is used in the multiple document interface, in pixels. + /// + SM_CXMENUSIZE = 54, + + /// + /// The minimum width of a window, in pixels. + /// + SM_CXMIN = 28, + + /// + /// The width of a minimized window, in pixels. + /// + SM_CXMINIMIZED = 57, + + /// + /// The width of a grid cell for a minimized window, in pixels. Each minimized window fits into a rectangle this size when arranged. + /// This value is always greater than or equal to SM_CXMINIMIZED. + /// + SM_CXMINSPACING = 47, + + /// + /// The minimum tracking width of a window, in pixels. The user cannot drag the window frame to a size smaller than these dimensions. + /// A window can override this value by processing the WM_GETMINMAXINFO message. + /// + SM_CXMINTRACK = 34, + + /// + /// The amount of border padding for captioned windows, in pixels. Windows XP/2000: This value is not supported. + /// + SM_CXPADDEDBORDER = 92, + + /// + /// The width of the screen of the primary display monitor, in pixels. This is the same value obtained by calling + /// GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES). + /// + SM_CXSCREEN = 0, + + /// + /// The width of a button in a window caption or title bar, in pixels. + /// + SM_CXSIZE = 30, + + /// + /// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels. + /// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. + /// This value is the same as SM_CXFRAME. + /// + SM_CXSIZEFRAME = 32, + + /// + /// The recommended width of a small icon, in pixels. Small icons typically appear in window captions and in small icon view. + /// + SM_CXSMICON = 49, + + /// + /// The width of small caption buttons, in pixels. + /// + SM_CXSMSIZE = 52, + + /// + /// The width of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors. + /// The SM_XVIRTUALSCREEN metric is the coordinates for the left side of the virtual screen. + /// + SM_CXVIRTUALSCREEN = 78, + + /// + /// The width of a vertical scroll bar, in pixels. + /// + SM_CXVSCROLL = 2, + + /// + /// The height of a window border, in pixels. This is equivalent to the SM_CYEDGE value for windows with the 3-D look. + /// + SM_CYBORDER = 6, + + /// + /// The height of a caption area, in pixels. + /// + SM_CYCAPTION = 4, + + /// + /// The height of a cursor, in pixels. The system cannot create cursors of other sizes. + /// + SM_CYCURSOR = 14, + + /// + /// This value is the same as SM_CYFIXEDFRAME. + /// + SM_CYDLGFRAME = 8, + + /// + /// The height of the rectangle around the location of a first click in a double-click sequence, in pixels. + /// The second click must occur within the rectangle defined by SM_CXDOUBLECLK and SM_CYDOUBLECLK for the system to consider + /// the two clicks a double-click. The two clicks must also occur within a specified time. To set the height of the double-click + /// rectangle, call SystemParametersInfo with SPI_SETDOUBLECLKHEIGHT. + /// + SM_CYDOUBLECLK = 37, + + /// + /// The number of pixels above and below a mouse-down point that the mouse pointer can move before a drag operation begins. + /// This allows the user to click and release the mouse button easily without unintentionally starting a drag operation. + /// If this value is negative, it is subtracted from above the mouse-down point and added below it. + /// + SM_CYDRAG = 69, + + /// + /// The height of a 3-D border, in pixels. This is the 3-D counterpart of SM_CYBORDER. + /// + SM_CYEDGE = 46, + + /// + /// The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels. + /// SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border. + /// This value is the same as SM_CYDLGFRAME. + /// + SM_CYFIXEDFRAME = 8, + + /// + /// The height of the top and bottom edges of the focus rectangle drawn byDrawFocusRect. + /// This value is in pixels. + /// Windows 2000: This value is not supported. + /// + SM_CYFOCUSBORDER = 84, + + /// + /// This value is the same as SM_CYSIZEFRAME. + /// + SM_CYFRAME = 33, + + /// + /// The height of the client area for a full-screen window on the primary display monitor, in pixels. + /// To get the coordinates of the portion of the screen not obscured by the system taskbar or by application desktop toolbars, + /// call the SystemParametersInfo function with the SPI_GETWORKAREA value. + /// + SM_CYFULLSCREEN = 17, + + /// + /// The height of a horizontal scroll bar, in pixels. + /// + SM_CYHSCROLL = 3, + + /// + /// The default height of an icon, in pixels. The LoadIcon function can load only icons with the dimensions SM_CXICON and SM_CYICON. + /// + SM_CYICON = 12, + + /// + /// The height of a grid cell for items in large icon view, in pixels. Each item fits into a rectangle of size + /// SM_CXICONSPACING by SM_CYICONSPACING when arranged. This value is always greater than or equal to SM_CYICON. + /// + SM_CYICONSPACING = 39, + + /// + /// For double byte character set versions of the system, this is the height of the Kanji window at the bottom of the screen, in pixels. + /// + SM_CYKANJIWINDOW = 18, + + /// + /// The default height, in pixels, of a maximized top-level window on the primary display monitor. + /// + SM_CYMAXIMIZED = 62, + + /// + /// The default maximum height of a window that has a caption and sizing borders, in pixels. This metric refers to the entire desktop. + /// The user cannot drag the window frame to a size larger than these dimensions. A window can override this value by processing + /// the WM_GETMINMAXINFO message. + /// + SM_CYMAXTRACK = 60, + + /// + /// The height of a single-line menu bar, in pixels. + /// + SM_CYMENU = 15, + + /// + /// The height of the default menu check-mark bitmap, in pixels. + /// + SM_CYMENUCHECK = 72, + + /// + /// The height of menu bar buttons, such as the child window close button that is used in the multiple document interface, in pixels. + /// + SM_CYMENUSIZE = 55, + + /// + /// The minimum height of a window, in pixels. + /// + SM_CYMIN = 29, + + /// + /// The height of a minimized window, in pixels. + /// + SM_CYMINIMIZED = 58, + + /// + /// The height of a grid cell for a minimized window, in pixels. Each minimized window fits into a rectangle this size when arranged. + /// This value is always greater than or equal to SM_CYMINIMIZED. + /// + SM_CYMINSPACING = 48, + + /// + /// The minimum tracking height of a window, in pixels. The user cannot drag the window frame to a size smaller than these dimensions. + /// A window can override this value by processing the WM_GETMINMAXINFO message. + /// + SM_CYMINTRACK = 35, + + /// + /// The height of the screen of the primary display monitor, in pixels. This is the same value obtained by calling + /// GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, VERTRES). + /// + SM_CYSCREEN = 1, + + /// + /// The height of a button in a window caption or title bar, in pixels. + /// + SM_CYSIZE = 31, + + /// + /// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels. + /// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. + /// This value is the same as SM_CYFRAME. + /// + SM_CYSIZEFRAME = 33, + + /// + /// The height of a small caption, in pixels. + /// + SM_CYSMCAPTION = 51, + + /// + /// The recommended height of a small icon, in pixels. Small icons typically appear in window captions and in small icon view. + /// + SM_CYSMICON = 50, + + /// + /// The height of small caption buttons, in pixels. + /// + SM_CYSMSIZE = 53, + + /// + /// The height of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors. + /// The SM_YVIRTUALSCREEN metric is the coordinates for the top of the virtual screen. + /// + SM_CYVIRTUALSCREEN = 79, + + /// + /// The height of the arrow bitmap on a vertical scroll bar, in pixels. + /// + SM_CYVSCROLL = 20, + + /// + /// The height of the thumb box in a vertical scroll bar, in pixels. + /// + SM_CYVTHUMB = 9, + + /// + /// Nonzero if User32.dll supports DBCS; otherwise, 0. + /// + SM_DBCSENABLED = 42, + + /// + /// Nonzero if the debug version of User.exe is installed; otherwise, 0. + /// + SM_DEBUG = 22, + + /// + /// Nonzero if the current operating system is Windows 7 or Windows Server 2008 R2 and the Tablet PC Input + /// service is started; otherwise, 0. The return value is a bitmask that specifies the type of digitizer input supported by the device. + /// For more information, see Remarks. + /// Windows Server 2008, Windows Vista, and Windows XP/2000: This value is not supported. + /// + SM_DIGITIZER = 94, + + /// + /// Nonzero if Input Method Manager/Input Method Editor features are enabled; otherwise, 0. + /// SM_IMMENABLED indicates whether the system is ready to use a Unicode-based IME on a Unicode application. + /// To ensure that a language-dependent IME works, check SM_DBCSENABLED and the system ANSI code page. + /// Otherwise the ANSI-to-Unicode conversion may not be performed correctly, or some components like fonts + /// or registry settings may not be present. + /// + SM_IMMENABLED = 82, + + /// + /// Nonzero if there are digitizers in the system; otherwise, 0. SM_MAXIMUMTOUCHES returns the aggregate maximum of the + /// maximum number of contacts supported by every digitizer in the system. If the system has only single-touch digitizers, + /// the return value is 1. If the system has multi-touch digitizers, the return value is the number of simultaneous contacts + /// the hardware can provide. Windows Server 2008, Windows Vista, and Windows XP/2000: This value is not supported. + /// + SM_MAXIMUMTOUCHES = 95, + + /// + /// Nonzero if the current operating system is the Windows XP, Media Center Edition, 0 if not. + /// + SM_MEDIACENTER = 87, + + /// + /// Nonzero if drop-down menus are right-aligned with the corresponding menu-bar item; 0 if the menus are left-aligned. + /// + SM_MENUDROPALIGNMENT = 40, + + /// + /// Nonzero if the system is enabled for Hebrew and Arabic languages, 0 if not. + /// + SM_MIDEASTENABLED = 74, + + /// + /// Nonzero if a mouse is installed; otherwise, 0. This value is rarely zero, because of support for virtual mice and because + /// some systems detect the presence of the port instead of the presence of a mouse. + /// + SM_MOUSEPRESENT = 19, + + /// + /// Nonzero if a mouse with a horizontal scroll wheel is installed; otherwise 0. + /// + SM_MOUSEHORIZONTALWHEELPRESENT = 91, + + /// + /// Nonzero if a mouse with a vertical scroll wheel is installed; otherwise 0. + /// + SM_MOUSEWHEELPRESENT = 75, + + /// + /// The least significant bit is set if a network is present; otherwise, it is cleared. The other bits are reserved for future use. + /// + SM_NETWORK = 63, + + /// + /// Nonzero if the Microsoft Windows for Pen computing extensions are installed; zero otherwise. + /// + SM_PENWINDOWS = 41, + + /// + /// This system metric is used in a Terminal Services environment to determine if the current Terminal Server session is + /// being remotely controlled. Its value is nonzero if the current session is remotely controlled; otherwise, 0. + /// You can use terminal services management tools such as Terminal Services Manager (tsadmin.msc) and shadow.exe to + /// control a remote session. When a session is being remotely controlled, another user can view the contents of that session + /// and potentially interact with it. + /// + SM_REMOTECONTROL = 0x2001, + + /// + /// This system metric is used in a Terminal Services environment. If the calling process is associated with a Terminal Services + /// client session, the return value is nonzero. If the calling process is associated with the Terminal Services console session, + /// the return value is 0. + /// Windows Server 2003 and Windows XP: The console session is not necessarily the physical console. + /// For more information, seeWTSGetActiveConsoleSessionId. + /// + SM_REMOTESESSION = 0x1000, + + /// + /// Nonzero if all the display monitors have the same color format, otherwise, 0. Two displays can have the same bit depth, + /// but different color formats. For example, the red, green, and blue pixels can be encoded with different numbers of bits, + /// or those bits can be located in different places in a pixel color value. + /// + SM_SAMEDISPLAYFORMAT = 81, + + /// + /// This system metric should be ignored; it always returns 0. + /// + SM_SECURE = 44, + + /// + /// The build number if the system is Windows Server 2003 R2; otherwise, 0. + /// + SM_SERVERR2 = 89, + + /// + /// Nonzero if the user requires an application to present information visually in situations where it would otherwise present + /// the information only in audible form; otherwise, 0. + /// + SM_SHOWSOUNDS = 70, + + /// + /// Nonzero if the current session is shutting down; otherwise, 0. Windows 2000: This value is not supported. + /// + SM_SHUTTINGDOWN = 0x2000, + + /// + /// Nonzero if the computer has a low-end (slow) processor; otherwise, 0. + /// + SM_SLOWMACHINE = 73, + + /// + /// Nonzero if the current operating system is Windows 7 Starter Edition, Windows Vista Starter, or Windows XP Starter Edition; otherwise, 0. + /// + SM_STARTER = 88, + + /// + /// Nonzero if the meanings of the left and right mouse buttons are swapped; otherwise, 0. + /// + SM_SWAPBUTTON = 23, + + /// + /// Nonzero if the current operating system is the Windows XP Tablet PC edition or if the current operating system is Windows Vista + /// or Windows 7 and the Tablet PC Input service is started; otherwise, 0. The SM_DIGITIZER setting indicates the type of digitizer + /// input supported by a device running Windows 7 or Windows Server 2008 R2. For more information, see Remarks. + /// + SM_TABLETPC = 86, + + /// + /// The coordinates for the left side of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. + /// The SM_CXVIRTUALSCREEN metric is the width of the virtual screen. + /// + SM_XVIRTUALSCREEN = 76, + + /// + /// The coordinates for the top of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. + /// The SM_CYVIRTUALSCREEN metric is the height of the virtual screen. + /// + SM_YVIRTUALSCREEN = 77, + } + + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetWindowPlacement( + IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); + + /// + /// Retrieves the show state and the restored, minimized, and maximized positions of the specified window. + /// + /// + /// A handle to the window. + /// + /// + /// A pointer to the WINDOWPLACEMENT structure that receives the show state and position information. + /// + /// Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT). GetWindowPlacement fails if lpwndpl-> length is not set correctly. + /// + /// + /// + /// If the function succeeds, the return value is nonzero. + /// + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + [DllImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); + + public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll")] + public static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, + IntPtr lParam); + + public static List EnumerateProcessWindowHandles(int processId) + { + var handles = new List(); + + foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) + EnumThreadWindows(thread.Id, + (hWnd, lParam) => + { + handles.Add(hWnd); + return true; + }, IntPtr.Zero); + + return handles; + } + + public const uint WM_GETTEXT = 0x000D; + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, + StringBuilder lParam); + } +} \ No newline at end of file diff --git a/DesktopRestorer/FodyWeavers.xml b/DesktopRestorer/FodyWeavers.xml new file mode 100644 index 0000000..4e68ed1 --- /dev/null +++ b/DesktopRestorer/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DesktopRestorer/FodyWeavers.xsd b/DesktopRestorer/FodyWeavers.xsd new file mode 100644 index 0000000..2f1b8aa --- /dev/null +++ b/DesktopRestorer/FodyWeavers.xsd @@ -0,0 +1,54 @@ + + + + + + + + + + + Used to control if the On_PropertyName_Changed feature is enabled. + + + + + Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. + + + + + Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. + + + + + Used to control if equality checks should use the Equals method resolved from the base class. + + + + + Used to control if equality checks should use the static Equals method resolved from the base class. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/DesktopRestorer/MainWindow.xaml b/DesktopRestorer/MainWindow.xaml index fc161af..a62e2f9 100644 --- a/DesktopRestorer/MainWindow.xaml +++ b/DesktopRestorer/MainWindow.xaml @@ -7,8 +7,34 @@ mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> - - - + + + + + + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/DesktopRestorer/MainWindow.xaml.cs b/DesktopRestorer/MainWindow.xaml.cs index 87d9480..606646b 100644 --- a/DesktopRestorer/MainWindow.xaml.cs +++ b/DesktopRestorer/MainWindow.xaml.cs @@ -1,8 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows; @@ -17,182 +17,109 @@ namespace DesktopRestorer { - - - - - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : Window + public class MonitorVM { - - [StructLayout(LayoutKind.Sequential)] - public struct RECT - { - public int left; - public int top; - public int right; - public int bottom; - } - - [StructLayout(LayoutKind.Sequential)] - public struct POINT + public MonitorVM() { - public long x; - public long y; - } - - [StructLayout(LayoutKind.Sequential)] - struct WINDOWPLACEMENT - { - public uint length; - public uint flags; - public uint showCmd; - public POINT ptMinPosition; - public POINT ptMaxPosition; - public RECT rcNormalPosition; - public RECT rcDevice; - } - enum ShowWindowCommands - { - /// - /// Hides the window and activates another window. - /// - Hide = 0, - /// - /// Activates and displays a window. If the window is minimized or - /// maximized, the system restores it to its original size and position. - /// An application should specify this flag when displaying the window - /// for the first time. - /// - Normal = 1, - /// - /// Activates the window and displays it as a minimized window. - /// - ShowMinimized = 2, - /// - /// Maximizes the specified window. - /// - Maximize = 3, // is this the right value? - /// - /// Activates the window and displays it as a maximized window. - /// - ShowMaximized = 3, - /// - /// Displays a window in its most recent size and position. This value - /// is similar to , except - /// the window is not activated. - /// - ShowNoActivate = 4, - /// - /// Activates the window and displays it in its current size and position. - /// - Show = 5, - /// - /// Minimizes the specified window and activates the next top-level - /// window in the Z order. - /// - Minimize = 6, - /// - /// Displays the window as a minimized window. This value is similar to - /// , except the - /// window is not activated. - /// - ShowMinNoActive = 7, - /// - /// Displays the window in its current size and position. This value is - /// similar to , except the - /// window is not activated. - /// - ShowNA = 8, - /// - /// Activates and displays the window. If the window is minimized or - /// maximized, the system restores it to its original size and position. - /// An application should specify this flag when restoring a minimized window. - /// - Restore = 9, - /// - /// Sets the show state based on the SW_* value specified in the - /// STARTUPINFO structure passed to the CreateProcess function by the - /// program that started the application. - /// - ShowDefault = 10, - /// - /// Windows 2000/XP: Minimizes a window, even if the thread - /// that owns the window is not responding. This flag should only be - /// used when minimizing windows from a different thread. - /// - ForceMinimize = 11 + var enumMonitors = ExternalMethods.EnumMonitors(); + var minX = enumMonitors.Min(monitorinfoex => monitorinfoex.Monitor.Left); + var minY = enumMonitors.Min(monitorinfoex => monitorinfoex.Monitor.Top); + var maxX = enumMonitors.Max(monitorinfoex => monitorinfoex.Monitor.Right); + var maxY = enumMonitors.Max(monitorinfoex => monitorinfoex.Monitor.Bottom); + Width = maxX - minX; + Height = maxY - minY; + Monitors = enumMonitors.Select(monitorinfoex => new MonVM() + { + Left = monitorinfoex.Monitor.Left+minX, + Top=monitorinfoex.Monitor.Top+minY, + Width = monitorinfoex.Monitor.Right - monitorinfoex.Monitor.Left, + Height = monitorinfoex.Monitor.Bottom - monitorinfoex.Monitor.Top + }).ToList(); + + /*foreach (var monitorinfoex in enumMonitors) + { + var rectangle = new Rectangle(){StrokeThickness = 10,Stroke = Brushes.Black}; + rectangle.SetValue(Canvas.LeftProperty,(double)monitorinfoex.Monitor.Left+minX); + rectangle.SetValue(Canvas.TopProperty,(double)monitorinfoex.Monitor.Top+minY); + rectangle.Width = monitorinfoex.Monitor.Right - monitorinfoex.Monitor.Left; + rectangle.Height = monitorinfoex.Monitor.Bottom - monitorinfoex.Monitor.Top; + DisplayCanvas.Children.Add(rectangle); + }*/ } - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow); - - [DllImport("user32.dll", SetLastError = true)] - static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect); - - [DllImport("user32.dll", SetLastError = true)] - static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint); - - [DllImport("user32.dll", SetLastError = true)] - static extern bool SetWindowPlacement( - IntPtr hWnd,ref WINDOWPLACEMENT lpwndpl); + public List Monitors { get; } + public int Width { get; set; } - delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); - -[DllImport("user32.dll")] -static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, - IntPtr lParam); - -static List EnumerateProcessWindowHandles(int processId) -{ - var handles = new List(); + public int Height { get; set; } + } - foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) - EnumThreadWindows(thread.Id, - (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); + public class MonVM : INotifyPropertyChanged + { + public int Left { get; set; } - return handles; -} + public int Top { get; set; } + public int Width { get; set; } -private const uint WM_GETTEXT = 0x000D; + public int Height { get; set; } + public event PropertyChangedEventHandler PropertyChanged; -[DllImport("user32.dll", CharSet = CharSet.Auto)] -static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, - StringBuilder lParam); + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { public MainWindow() { InitializeComponent(); + var vx = ExternalMethods.GetSystemMetrics(ExternalMethods.SystemMetric.SM_CXVIRTUALSCREEN); + var vy = ExternalMethods.GetSystemMetrics(ExternalMethods.SystemMetric.SM_CYVIRTUALSCREEN); + +DisplayItems.DataContext = new MonitorVM(); var processes = Process.GetProcesses(); - TB.Text = string.Join("\n", processes.Select(process => process.ProcessName)); - - foreach (var handle in EnumerateProcessWindowHandles( - Process.GetProcessesByName("explorer").First().Id)) - { - StringBuilder message = new StringBuilder(1000); - SendMessage(handle, WM_GETTEXT, message.Capacity, message); - Console.WriteLine(message); - } + foreach (var handle in + processes.Where(p => p.ProcessName == "chrome") + .SelectMany(process => ExternalMethods.EnumerateProcessWindowHandles(process.Id))) + + { + var message = new StringBuilder(1000); + ExternalMethods.SendMessage(handle, ExternalMethods.WM_GETTEXT, message.Capacity, message); + var rect = new ExternalMethods.RECT(); + ExternalMethods.GetWindowRect(handle, ref rect); + ExternalMethods.WINDOWPLACEMENT plcacement = new ExternalMethods.WINDOWPLACEMENT(); + ExternalMethods.GetWindowPlacement(handle, ref plcacement); +// if (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0) +// { +// if (message.Length == 0) +// continue; +// } + + if (!ExternalMethods.IsWindowVisible(handle)) + continue; + TB.Text += $"{message} {rect.left} {rect.top} {rect.right} {rect.bottom} \n"; + + } } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { - Process[] processes = Process.GetProcessesByName("notepad"); - + var processes = Process.GetProcessesByName("notepad"); - foreach (Process p in processes) + foreach (var p in processes) { - IntPtr handle = p.MainWindowHandle; - RECT Rect = new RECT(); - if (GetWindowRect(handle, ref Rect)) - MoveWindow(handle, Rect.left-5, Rect.top-5, 1280, 720, true); - Task.Delay(5000).ContinueWith(task => { ShowWindow(handle, ShowWindowCommands.Maximize); }); + var handle = p.MainWindowHandle; + ExternalMethods.RECT Rect = new ExternalMethods.RECT(); + if (ExternalMethods.GetWindowRect(handle, ref Rect)) + ExternalMethods.MoveWindow(handle, Rect.left - 5, Rect.top - 5, 1280, 720, true); + Task.Delay(5000).ContinueWith(task => { ExternalMethods.ShowWindow(handle, ExternalMethods.ShowWindowCommands.Maximize); }); } } } -} +} \ No newline at end of file diff --git a/DesktopRestorer/Properties/Resources.Designer.cs b/DesktopRestorer/Properties/Resources.Designer.cs index b4ebeab..5ad8f85 100644 --- a/DesktopRestorer/Properties/Resources.Designer.cs +++ b/DesktopRestorer/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace DesktopRestorer.Properties -{ - - +namespace DesktopRestorer.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace DesktopRestorer.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DesktopRestorer.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/DesktopRestorer/Properties/Settings.Designer.cs b/DesktopRestorer/Properties/Settings.Designer.cs index fabf09d..debdba3 100644 --- a/DesktopRestorer/Properties/Settings.Designer.cs +++ b/DesktopRestorer/Properties/Settings.Designer.cs @@ -8,21 +8,17 @@ // //------------------------------------------------------------------------------ -namespace DesktopRestorer.Properties -{ - - +namespace DesktopRestorer.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/DesktopRestorer/packages.config b/DesktopRestorer/packages.config new file mode 100644 index 0000000..ff95334 --- /dev/null +++ b/DesktopRestorer/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/RestorerTest/Properties/AssemblyInfo.cs b/RestorerTest/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..13fc982 --- /dev/null +++ b/RestorerTest/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("RestorerTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RestorerTest")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("a1dff3d1-506b-4021-bbae-2813cbbf2503")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/RestorerTest/RestorerTest.csproj b/RestorerTest/RestorerTest.csproj new file mode 100644 index 0000000..2693e16 --- /dev/null +++ b/RestorerTest/RestorerTest.csproj @@ -0,0 +1,84 @@ + + + + + + Debug + AnyCPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503} + Library + Properties + RestorerTest + RestorerTest + v4.7.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + ..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll + + + ..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll + + + ..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll + + + ..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll + + + + + + + + + + + + + + + {7d26b012-0e8d-40c2-bd6a-1a75791272be} + DesktopRestorer + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/RestorerTest/UnitTest1.cs b/RestorerTest/UnitTest1.cs new file mode 100644 index 0000000..ba4fa07 --- /dev/null +++ b/RestorerTest/UnitTest1.cs @@ -0,0 +1,13 @@ +using System; +using Xunit; + +namespace RestorerTest +{ + public class UnitTest1 + { + [Fact] + public void TestMethod1() + { + } + } +} diff --git a/RestorerTest/packages.config b/RestorerTest/packages.config new file mode 100644 index 0000000..e8bc01f --- /dev/null +++ b/RestorerTest/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/WindowRestorer.sln b/WindowRestorer.sln index 0aadc4e..19f75e6 100644 --- a/WindowRestorer.sln +++ b/WindowRestorer.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.28307.329 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesktopRestorer", "DesktopRestorer\DesktopRestorer.csproj", "{7D26B012-0E8D-40C2-BD6A-1A75791272BE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestorerTest", "RestorerTest\RestorerTest.csproj", "{A1DFF3D1-506B-4021-BBAE-2813CBBF2503}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,26 @@ Global {7D26B012-0E8D-40C2-BD6A-1A75791272BE}.Release|x64.Build.0 = Release|Any CPU {7D26B012-0E8D-40C2-BD6A-1A75791272BE}.Release|x86.ActiveCfg = Release|Any CPU {7D26B012-0E8D-40C2-BD6A-1A75791272BE}.Release|x86.Build.0 = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|ARM.ActiveCfg = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|ARM.Build.0 = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|ARM64.Build.0 = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|x64.ActiveCfg = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|x64.Build.0 = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|x86.ActiveCfg = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Debug|x86.Build.0 = Debug|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|Any CPU.Build.0 = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|ARM.ActiveCfg = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|ARM.Build.0 = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|ARM64.ActiveCfg = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|ARM64.Build.0 = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|x64.ActiveCfg = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|x64.Build.0 = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|x86.ActiveCfg = Release|Any CPU + {A1DFF3D1-506B-4021-BBAE-2813CBBF2503}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE