WindowsPosSaveNRestore is a tool to save the position of windows for later restore
This is primarily useful if you frequently change display configuration, say add/remove external monitor(s) e.g. by docking, or turning a device with autorotate active.
Windows also has the bug that it sometimes cram all open windows (and icons [+]) on the primary screen on sleep.
UPDATE 2020: I added the ability to remember all open windows temporarily, not writing it to disk. Can be handy as an extended version of what Win+D can do, if you do a little more app open/close/minimise before you want to restore all your windows, where Win+D might minimize the later opened windows rather than restore all the minimized ones… (And it now has an icon, and use the updated DPI_Per_Monitor.cs working on creators update)
WnPosSaveNRestore saves positions in an XML-file, in a section index by a key containing the current screen-configuration
(More readably available saved in subkey DisplayInformation)
e.g.:
<Tot_X_-636_Y_-2160_Width_3840_Height_3600_List_X_0_Y_0_Width_2560_Height_1390_X_-636_Y_-2160_Width_3840_Height_2160>
<DisplayInformation>
<Virtual>{X=-636,Y=-2160,Width=3840,Height=3600}</Virtual>
<Display>{X=0,Y=0,Width=2560,Height=1390}</Display>
<Display>{X=-636,Y=-2160,Width=3840,Height=2160}</Display>
</DisplayInformation>
Reflecting this logical configuration:
Note the height of the primary display. As I have taskbar always on, this is the physical height minus the height of the taskbar scaled with the scale factor of the monitor (with current size and scale ths gives 140 – 40 * 125%).
To initiate you select the window(s) you want to save in the lower pane, and clicks save.
To restore position(s) you can later select the saved items, and choose restore.
The app can be used with * and ? wildcards in the masks – you would need to edit the WindowsPosSaveNRestore.XML created manually to do so.
(Typical examples are apps that reflects the active document in the window title, and you might like that part replaced with an asterisk for ‘anything’, for programs where you do not have several instances opened simultaneously)
If you save a process that is matching an existing mask, only the placement is updated, not the masks.
Example node
<Process>
<ProcessName>firefox</ProcessName>
<Path>*\\Mozilla Firefox\\firefox.exe</Path>
<Title>*Mozilla Firefox</Title>
<flags>0</flags>
<Placement>
<showWCmd>Normal</showWCmd>
<Left>-636</Left>
<Top>-1085</Top>
<Right>1260</Right>
<Bottom>-1</Bottom>
</Placement>
</Process>
Note that coordinates are STRETCHED if Windows is not set for 100% under Display Settings and that they can be negative, for secondary monitors logically above or left of the primary.
If you use BLANK in the masks for ProgramName, Path or Title, it will match anything.
Do not use blank in all three unless you want EVERY window to be displayed on top of each other – could make sense under rare circumstances, e.g. with all windows maximized.
The Rename Screen Settings is to change the system-generated name of the monitor constellation with something more user-readable. It is checked to be a valid XML key, so no fancy stuff!! A-Z, a-z, 0-9, underscore, minus and period should be accepted. Most begin with letter or underscore.
The 3s Focus Selected is to cycle through the selected processes, and show each window for *surprise* 3 seconds, before returning to the program
The source is quite simple C#, with no fancy stuff. (the most ‘fancy’ is that the checkboxlist are filled not with plain text, but with objects with a ToString() override function for what is displayed in the lists)
Source: WindowsPosSaveNRestore_Source
Exe: WindowsPosSaveNRestore_EXE
Please fell free to add any suggestions in the comment below – no guarantee it will be implemented though.
I have updated it with a few lines of code to make it “Per Monitor DPI Aware“, see other post here. So no more woolly scaling. but odd results if the primary monitor was not 100% at login….
It an be called with a /RestoreAll=<SectionID> option, Where <SectionId> is the name of the outer section, Note that this section can be renamed
e.g. <fullpath>\WindowsPosSaveNRestore.exe /RestoreAll=Disp_100pctQHD_100pctUHD
If you experience problems, please try this older Beta, as a first resort, to help debug.
BETA Exe: WindowsPosSaveNRestore_BETA_EXE
[+] For restoring icons I recommend: https://www.softwareok.com/?Freeware/DesktopOK


This is really neat 🙂 I like having my windows where I place them but often get moved, or worse, resized, whenever running a program in exclusive fullscreen.
Will post ideas, if I have any. Right now I’d like command line switches, like
WindowsPosSaveNRestore.exe -restoreallto restore everything I saved without opening the program.
Also a side note, it works for elevated programs too if you run WindowsPosSaveNRestore as admin.
Thanks I made a new version where you can rename the ugly names of the configuration, and it already has restore by command-line, so we can just add a shortcut somewhere. (has not posted it yet due to the scale issues below) Posted a BETA… But the last days I really tried to find a workaround for a strange bug in the scaling system. (a new version is on its way here as well) The problem is that IF i log in with a setting of 100% on the PRIMARY screen, then all zoom factors on primary and secondary works just fine, no matter what the second monitor was at log in… BUT if the primary monitor was NOT 100% at log in odd things happens at most zoom rates. It is as if it scale the forms and ‘all’ CONTROL-elements correct BUT the TEXT that should go with the controls scale by an additional factor of the log/in scale-factor of the primary. So the text get too big for its slots on the form…. Except for a combobox that has the text scaled correct!!! To make things more odd, the Visual studio form-designer does not work well if the… Read more »
Here is the primary set to 200%…..

and how it displays on a secondary set to 100%, note the huge tick/boxes and scrollbars….
Note that they display in different scale in here – click each..
Do other programs scale properly in these conditions? I know on 10 you can adjust the scaling on the fly without the need to log off/on, but it does a job much like in your screenshots. I know because when I tried it, it defaulted my monitor to a value higher than 100% and when switching to 100% the same window could have both larger and smaller components. Text was generally larger and buttons/tabs smaller than they should.
Does the beta exe work for you? It gives me this when I run it:
It seems to be a .Net bug. but SOME programs scale correctly. I do not know if any .Net programs using the AutoScaleMode=Font does…. Please start by renaming your .XML, and retry, as I have changed slightly in the structure (sorry) Note also that after the scaling has been introduced, this have messed with the coordinates. So restore with the old app, and save with the beta (e.g. in a temp dir) I added the .pdb debug info file to the zip, please try again with this, so we can pinpoint where it is. I tried it here with both one monitor, and a second one logically above and left of the primary (so negative coordinates are supported) Here it basically works (with the scaling issues) I have an idea of additional syntax to the XML, so several configurations can refer to the same info. Say you change the scale on one monitor, then most likely you want the positions on the other one preserves. …But things might get messy if an app cross the border between the monitor by just a few pixels… I imagine something designed for apps completely contained on a monitor, and then holds the position… Read more »
Yep, tried without the xml file and the same result. I have Net framework 4.6.2 (4.6.01590) installed if it helps.
And including the .pdb file did not give any further info on the exception?
Dot net should be reasonably backwards compatible. I compiled it for .net 4, not to expect too much of the client…
Yes, the same with or without the pdb file. I tried pre-creating an empty “WindowsPosSaveNRestore.XML” file with no luck.
Are you on 32 or 64 bit windows?
It’s 64-bit Winows 7
AH! That might explain it. I’m on Win10 So most likely something not available on Win7, that I lack some try-catch around 🙂
I made a new beta, where some of the debug stuff has been commented out – with a little luck that will do the trick… and make it more suitable for W7.
🙂
Yes, this last beta (size: 32 256 bytes) works 🙂 No problems at all. Works without the pdb file too.
Command line switches working too!
Great! 🙂
(the .pdb file is just for extra info on where it crashed if it throws an unhandled exception)
OH, I forgot to post that I have updated with a newer variant with rename. 🙂
Add: And show of selected process, this can be useful if you got doublet processes active
I was about to complain that it returned an error when renaming the screen config key through UI, but I downloaded the beta exe. The current stable exe works perfectly 🙂
AH! That explains it. I’m on Win10 So most likely something not available on Win7, that I lack some try-catch around 🙂
i have a little extra here that might be the culprit
[DllImport(“SHCore.dll”)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
private enum PROCESS_DPI_AWARENESS {
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
[DllImport(“user32.dll”, SetLastError = true)]
static extern bool SetProcessDPIAware();
static float MeanDPIprimary = 96f;
public enum DpiType
{
Effective = 0,
Angular = 1,
Raw = 2,
}
[DllImport(“Shcore.dll”)]
private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);
[DllImport(“User32.dll”)]
private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);