sweept Posted October 14, 2010 Posted October 14, 2010 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..
allen2 Posted October 14, 2010 Posted October 14, 2010 Something based on handle.exe (from sysinternals) or autoit should work.
allen2 Posted October 14, 2010 Posted October 14, 2010 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=0dim $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] EndIfNextfor $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)) nextelse exitendifFunc IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Else Return 0 EndIfEndFuncFunc Isexplorer($handle) $pid = WinGetProcess($handle) if stringlower(_ProcessGetName($pid))="explorer.exe" then Return 1 Else Return 0 EndifEndFuncI 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.
sweept Posted October 18, 2010 Author Posted October 18, 2010 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 TIA
wakillon Posted January 29, 2011 Posted January 29, 2011 (edited) 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 January 29, 2011 by wakillon
CoffeeFiend Posted January 29, 2011 Posted January 29, 2011 @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)
wakillon Posted February 2, 2011 Posted February 2, 2011 (edited) @CoffeeFiendsweept 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 February 17, 2011 by wakillon
CoffeeFiend Posted February 2, 2011 Posted February 2, 2011 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)
wakillon Posted February 16, 2011 Posted February 16, 2011 (edited) If you want an other way...#include <Array.au3>$_WinShell = ObjCreate ( "Shell.Application" )$_WinList = $_WinShell.windowsGlobal $_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:///", "" ), "/", "\" ) )NextDo 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] & '"' )NextWorks for all opened directories ! Edited February 17, 2011 by wakillon
CoffeeFiend Posted February 18, 2011 Posted February 18, 2011 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...
wakillon Posted February 18, 2011 Posted February 18, 2011 @CoffeeFiendSo, you have really no chance with your windows 7No 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 NextEndFunc ;==> _RestartExplorer ( )
CoffeeFiend Posted February 19, 2011 Posted February 19, 2011 So, you have really no chance with your windows 7It'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 ! Good one.I don't know if Sweept will respond one dayYou 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)
sweept Posted February 4, 2013 Author Posted February 4, 2013 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 taskA small check for the Tweaking side of things see :http://smallvoid.com/article/winnt-explorer-process.htmlNot 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:00000000as 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
ppp Posted February 8, 2013 Posted February 8, 2013 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
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now