Jump to content

Recover open windows (explorer)


Recommended Posts

I'm looking for a script that can list all running available open windows on desktop!..

secondly kill *all processes of explorer.exe till there are none more running @foreground or @backgrounds lastly recover all X:\paths of all open windows listed from the first step using explorer.exe..

TIA for any help with this..

Link to comment
Share on other sites


As it is, it won't kill the process explorer used as windows manager but i didn't see the point to kill it.

So here is the autoit source:

#include <Process.au3>
dim $var
$var = WinList()
dim $n=0
dim $path[100][2]
For $i = 1 to $var[0][0]
If $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND Isexplorer($var[$i][1]) AND $var[$i][0] <> "Program Manager" Then
MsgBox(0, "Details", "Title=" & $var[$i][0] & @LF & "Handle=" & $var[$i][1])
$n=$n+1
$path[$n][0]=$var[$i][0]
$path[$n][1]=$var[$i][1]
EndIf
Next
for $i =1 to $n
winkill($path[$i][1])
next

$res=msgbox(36,"Restore","Restore Explorer windows ?" )
if $res=6 then
for $i=1 to $n
run("explorer " & chr(34) & $path[$i][0] & chr(34))
next
else
exit
endif
Func IsVisible($handle)
If BitAnd( WinGetState($handle), 2 ) Then
Return 1
Else
Return 0
EndIf

EndFunc

Func Isexplorer($handle)
$pid = WinGetProcess($handle)
if stringlower(_ProcessGetName($pid))="explorer.exe" then
Return 1
Else
Return 0
Endif
EndFunc

I usually wouldn't have done it (because i prefer to help people to learn how to do things instead of doing it for them) but i had a little time to waste and the idea was interesting for another project.

Link to comment
Share on other sites

Sorry, I did not practically see the ending results from alan's script but it may help bring the goal closer to what I need. of-course if any one can help on...

I'd like to think that it will act as a quick sort-Order to all previously found as *opened windows* neatly back into the task bar and with a new logical order accordingly to paths..etc, leaving out any previously recorded duplicate windows from the recovery process...

this should act like a quick refresh & "sort order" for the many windows that where open on the Desktop at the same time leaving out the dups.. etc (killing the background process of explorer mentioned in my main post..isnt an essential step anymore..)

I cant help wondering if there is some already made tool that can precisely do this neatly, already :rolleyes::thumbup

TIA

Link to comment
Share on other sites

  • 3 months later...

Another way ...


; Restart explorer with opened windows

$_WinList = WinList ( "[REGEXPCLASS:(Explore|Cabinet)WClass]" )
Do
ProcessClose ( 'explorer.exe' )
Until Not ProcessExists ( 'explorer.exe' )
For $_I = 1 To $_WinList[0][0]
ConsoleWrite ( $_WinList[$_I][0] & @Crlf )
If FileExists ( $_WinList[$_I][0] ) Then Run ( 'explorer.exe "' & $_WinList[$_I][0] & '"' )
Next

Edited by wakillon
Link to comment
Share on other sites

@wakillon: that doesn't work at all (at least using Win 7 x64). It only gets the last part of the path (name of the Window), so FileExists always returns false, so nothing gets reopened, and you're left without explorer.exe running at all. It also wouldn't sort alphabetically nor remove dupes which is fixable (but you can't just try to reopen all windows like that either; some may open faster than others so opening them so quickly/at once will result in them not being sorted even if your "list" was). Even if you got the full folder paths from the window title, it wouldn't handle explorer windows opened in "special" locations properly (like "My Computer"), and killing explorer.exe is pretty drastic IMO.

Then again, allen2's solution didn't work either -- lots of messageboxes, every window flashed then it gave me the "restart?" screen for a split sec (and there you are thinking "oh no, I'm not sure I saved everything I had open!"), and if I click yes, then I just get a crapload of explorer windows opened -- all in My Documents...

I would personally use the SHDocVw COM object for this (it's meant exactly for this kind of stuff -- controlling explorer and IE windows).

To use such a COM object in C#, you have to manually add a reference to it by going to solution explorer > references > right click and select add > COM tab > double click on "Microsoft Internet Controls 1.1". This will add an interop assembly to your project. Then you can do something like this (very basic, no error handling or anything; too trivial to bother with a namespace, and you might have to increase the delay for slower computers -- it might be a good idea to make it an optional cmd line arg):


using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

static class Program
{
[STAThread]
static void Main(string[] args)
{
List<string> openedWindows = new List<string>();
//enum opened windows
SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();
foreach (SHDocVw.InternetExplorer e in shellWindows)
if (!e.FullName.Contains("iexplore"))
openedWindows.Add(e.Application.Document.Folder.Self.Path);

//close them
foreach (SHDocVw.InternetExplorer e in shellWindows)
if (!e.FullName.Contains("iexplore"))
e.Quit();

//get ordered, unique windows only
var fixedList = (from w in openedWindows orderby w select w).Distinct();

//restart previously opened windows
foreach (string s in fixedList)
{
Process.Start("Explorer.exe", s);
System.Threading.Thread.Sleep(500); //wait long enough otherwise they won't open up "ordered"
}
}
}

Scripting languages like vbscript/jscript would make it pretty easy to retrieve opened windows & reopen them, but sorting in vbscript (nevermind sorting unique entries) is a real pain (e.g. write your own bubble sort, or using a disconnected recordset or similar solution), whereas LINQ (in C# or other .NET languages) lets us do this in one short line (using orderby + distinct). Tested working under Win 7 x64 (english system)

Link to comment
Share on other sites

@CoffeeFiend

sweept said : I'm looking for a script that can list all running available open windows on desktop!..

secondly kill *all processes of explorer.exe till there are none more running @foreground or @backgrounds lastly recover all X:\paths of all open windows listed from the first step using explorer.exe..

TIA for any help with this..

So, Sorry for you if it doesn't work on 7-64bit, but on xpsp3-32bit it works well.

It doesn't return the name of the window but the entire path of the folder,

who permits to re-open them after...

FileExists returns false only for special folders who have already easy accessibles shortcuts.

And working with handles have no sense, because when explorer restarts these handles no longer exists ! ;)

Edited by wakillon
Link to comment
Share on other sites

It doesn't return the name of the window but the entire path of the folder,

who permits to re-open them after...

Well, not on every system for sure (at least, it doesn't on a vanilla install of Win 7), and it doesn't actually work on XP either if you didn't manually set the "Display the full path in the title bar" option either (because you *are* getting the name of the window and using that as a path), nor does it work on special folders. That was my point: it's not exactly a robust nor reliable way of doing this. Working with SHDocVw takes care of all that (works across OS'es, regardless of locale or settings, and works with special folders too)

Link to comment
Share on other sites

  • 2 weeks later...

If you want an other way...

#include <Array.au3>

$_WinShell = ObjCreate ( "Shell.Application" )

$_WinList = $_WinShell.windows

Global $_WinPath[1]

For $_I = 0 To $_WinList.count - 1

ConsoleWrite ( "Name : " & $_WinList.item ( $_I ).LocationName & @Crlf )

_ArrayAdd ( $_WinPath, StringReplace ( StringReplace ( StringReplace ( $_WinList.item ( $_I ).locationUrl, "%20", " " ), "File:///", "" ), "/", "\" ) )

Next

Do

ProcessClose ( 'explorer.exe' )

Until Not ProcessExists ( 'explorer.exe' )

ProcessWait ( 'explorer.exe', 5 )

For $_I = 1 To UBound ( $_WinPath ) -1

If FileExists ( $_WinPath[$_I] ) Then Run ( @WindowsDir & '\explorer.exe "' & $_WinPath[$_I] & '"' )

Next

Works for all opened directories ! :rolleyes:

Edited by wakillon
Link to comment
Share on other sites

Well, that's a step in the right direction. But:

-killing explorer.exe is still problematic. On Win7, you lose the start menu + taskbar + notification area -- they don't return on their own (you just get to wait for 5 seconds while staring at nothing), even if other windows reopen/script doesn't crash. You have to ctrl+shift+esc, then manually run explorer.exe by hand to get them back after running the script (it's easier to just use the .Quit() method of the Window object themselves -- it saves you from all this hassle)

-as per the user's request (read post 4), you still have to sort windows alphabetically (using _ArraySort() or something), and to not reopen duplicated entries (iterating through the list, keeping only unique entries), while not forgetting the required delay between opening each window (otherwise they'll reopen in a random order anyway). That was the whole point of the script (not just closing them all then reopening the exact same thing blindly which basically accomplishes nothing)

-should any explorer window be open in anything else than a "valid directory" (for example open network connections by running ncpa.cpl -- there's plenty of others though) before running the script, then some windows may not be reopened at all (or partially, depending in which order it sees them)

You're getting there...

Link to comment
Share on other sites

@CoffeeFiend

So, you have really no chance with your windows 7

No path in the title of your opened windows

and your explorer doesn't restart itself !

Which other surprises are coming ?

Like me, you should be back to XP !

I don't know if Sweept will respond one day, but i think this is approching :

#include <Array.au3>

_RestartExplorer ( )

Func _RestartExplorer ( )

Local $_WinShell = ObjCreate ( "Shell.Application" )

local $_WinList = $_WinShell.windows

Local $_WinPath[1]

For $_I = 0 To $_WinList.count - 1

ConsoleWrite ( "Name : " & $_WinList.item ( $_I ).locationName & @Crlf )

_ArrayAdd ( $_WinPath, StringReplace ( StringReplace ( StringReplace _

( $_WinList.item ( $_I ).locationUrl, "%20", " " ), "File:///", "" ), "/", "\" ) )

Next

_ArraySort ( $_WinPath )

Do

ProcessClose ( 'explorer.exe' )

Until Not ProcessExists ( 'explorer.exe' )

$_ExplorerPid = ProcessWait ( 'explorer.exe', 5 )

If Not $_ExplorerPid Then Run ( @WindowsDir & '\explorer.exe' )

For $_I = 1 To UBound ( $_WinPath ) -1

If FileExists ( $_WinPath[$_I] ) Then

$_ExplorerPid = Run ( @WindowsDir & '\explorer.exe "' & $_WinPath[$_I] & '"' )

ProcessWait ( $_ExplorerPid, 3 )

Sleep ( 1000 )

EndIf

Next

EndFunc ;==> _RestartExplorer ( )

Link to comment
Share on other sites

So, you have really no chance with your windows 7

It's not a matter of chance (nor "my" windows -- it's a very typical/vanilla install), it's just how it works (Vista would mostly do the same, and Win2008 series too). If anything, it's not shortcomings of the OS but of your script i.e. relying on optional features that are turned off by default, killing processes which you probably shouldn't, etc -- instead of standard ways that work just fine & reliably (like using the .Quit() method of the Window objects instead of killing explorer). You do have to keep such things in mind when you program or write scripts -- changes between different versions of the OS: security changes, varying locations/paths, different locales and so on (and everything that could go wrong, because it will)

Like me, you should be back to XP !

:lol: Good one.

I don't know if Sweept will respond one day

You posted something 3 months after the question was asked, so most likely not (you're basically wasting your time, unless you're doing it just for fun)

I haven't tried your last script, but I can already tell it's not looking for unique entries yet (i.e. if 2 explorer windows are opened in the same location, just reopen it once, as per the request in post #4), nor doing anything against explorer being opened in other places (like network connections) either. You're slowly getting there though (sorting + delay while reopening added)

Link to comment
Share on other sites

  • 1 year later...

I don't know if Sweept will respond one day, but i think this is approching :

Thanks wakillon & CoffeeFiend for the followups

wakillon, I didn't yet get to test your scripts but I will..

To further clarify my earlier posting as to what is my aiming with this :to do: by steps:

Little background first : With many explorer windowed paths open, sometimes its seems the task bar or tray menu will get corrupted or not function properly (like Freeze..)

because of another process of explorer that isn't functioning properly because of a corrupted child process launched with explorer..

one good example can be when search hangs up with the title (search results) "not responding"

These are the reasons why I wanted to clear all instances of the running explorer processes but not before I had a way to restore\refresh all instances of all opened explorer windows (paths) quickly ..

So there are only these things that need to be considered here:

Refreshing and reordering all open windows without duplicates. not before checking first if the desktop & taskbar (explorer process) is running smoothly with no other instance of bad \ Hanged_Up (explorer processes) possibly caused by a child process linked... End the offending child process gracefully if possible && if still found Hanged with no special resolutions.., Do a brute force ending of explorer.exe and start with the refreshing task

A small check for the Tweaking side of things

see :http://smallvoid.com/article/winnt-explorer-process.html

Not sure yet if "DesktopProcess" should get "1" or "0" with these, I've set it now to "0" .. was set to "1"

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"SeparateProcess "=dword:00000001
"DesktopProcess"=dword:00000000

as suggested, from a link on that page I have added these as well:

[HKEY_CURRENT_USER\Software\Microsoft\CTF]
"Disable Thread Input Manager"=dword:00000001

[HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar]
"ShowStatus"=dword:00000002
"ExtraIconsOnMinimized"=dword:00000000

[HKEY_CURRENT_USER\Software\Microsoft\CTF\MSUTB]
"ShowDeskBand"=dword:00000001

Link to comment
Share on other sites

Does anyone know how to do this in a Batch Script?


; Restart explorer with opened windows

$_WinList = WinList ( "[REGEXPCLASS:(Explore|Cabinet)WClass]" )
Do
ProcessClose ( 'explorer.exe' )
Until Not ProcessExists ( 'explorer.exe' )
For $_I = 1 To $_WinList[0][0]
ConsoleWrite ( $_WinList[$_I][0] & @Crlf )
If FileExists ( $_WinList[$_I][0] ) Then Run ( 'explorer.exe "' & $_WinList[$_I][0] & '"' )
Next

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...