I have done a lot of searching but I have not been able to discover a straightforward way to gently terminate the explorer shell in an XP batch file.
Why would I want to, you ask (since almost every time someone asks this someone else wants to know why)? The answer is simply this: I run a batch job at the end of the day which saves my toolbar configuration. When the explorer shell terminates normally, it writes the toolbar configuration to a registry key, which can then be exported and restored after I run CCleaner at the beginning of the week. If explorer is terminated with, for example, taskkill, it usually fails to write the registry key and the resulting export file does not always accurately reflect the current configuration of the toolbars.
I have tried using CMDOW "program manager" /cls but this just brings up the "Shut Down Windows" dialog - sometimes it makes the computer shut down even if you hit the "Cancel" button. Since bringing up the "Shut Down Windows" dialog and hitting "Cancel" while holding down "Ctrl, Alt, Shift" will cause explorer to gently die, I have looked at a vbs script using sendkeys but sending "%{F4}" assumes that the desktop is the foremost window. I thought I might try coding some HotKeyP macros - it has the capability of raising the "Shut Down Windows" dialog - but once the "Shut Down Windows" dialog is raised, HotKeyP can't seem to access it.
What message is Explorer receiving so that it knows to terminate gently as opposed to shut the whole computer down - that's what I want to know.
The following command line text will terminate any EXPLORER.EXE process but not shut down the computer.
taskkill /fi "imagename eq EXPLORER.EXE" /f /t
to know more about taskkill use the /? parameter.
I don't think Microsoft provides a way to do what you describe without scripting the Explorer UI. The prescribed way to close explorer and save all settings is to log off.
There are generally three ways to close a program:
TerminateProcess()
This causes the kernel to stop scheduling the process threads, and unloads the process from memory. As you rightly point out, this doesn't give explorer a chance to save its settings.
This is what "taskkill /f" does.
Send a WM_CLOSE message to the program's main window
Programs can decide to handle this however they want. Most will close, but Explorer treats it as a signal to log off, which is not what you want.
Use some program-specific method of asking it to shut down.
Explorer.exe does provide this via the GUI (ctrl+shift+rightclick on any non-button part of the start menu), but it does not provide a command-line way to do this.
If you are really set in what you want to do, you can use wscript or another UI scripting library to manipulate the GUI and perform option 3.
Related
I first need to offer the disclaimer that I am barely a novice when it comes to scripting or coding, so I might be doing this all wrong in the first place. I'm running into an issue with a script I had written in powershell a while ago that is used on several hundred computers in my company daily to automate starting a certain app that everyone uses. So far everyone else hasn't had an issue except one machine.
Normally when I run the script, it starts the services and cli for the program which opens in a new window. Then the script, still open behind that, sends all of the key commands to that cli window, pauses for a brief line of user input after which it closes that cli window, does a few other clean up tasks and closes out itself.
The only difference on this one machine that's not working is the script won't pass the keystrokes to the cli window. If I put them in manually including the normal user input, it finishes the rest of the script just fine, but the cli window is just not receiving the keystroke input from the main script.
The only part of the script that send the keystrokes to the cli window is a few lines of this:
[System.Windows.Forms.SendKeys]::SendWait("Text{Enter}")
I have tried using the sleep command before and in between the key commands to make sure it's not going through the keystrokes to early. I've checked and windows had gone through an Update two days ago, but we would've heard about this issue right then if that was it. I'm at a loss for what the issue could be and would apreciate and help, tips, or direction to help figure this one out.
Is the console window the active window when the keys are sent? The documentation for the class you are calling indicates that it sends the keys to the active window. Not only that, but the documentation also seems to indicate that there are some issues that developers have run into when using that class to sends keys. I would try using the autoit powershell module instead. Autoit is its own scripting language which specializes in automating windows processes and being capable of automating interactions with windows forms, but also comes bundled with its own powershell module that I think is exactly what you need, so I would download the portable "zip" package, extract the powershell module from "Autoitx", and that should help you accomplish what you need
PowerShell automation especially when using SendKeys can / is glitchy due to many varying reasons. Can you use SendKeys sure, but you have to know the environment it will be run in and the needed performance details. Hence your futzing/guessing with Sleep.
There are purpose-built tools to help.
Auto HotKey
'PowerShell auto hotkey'
or the UIAutomation tool
'PowerShell automating other applications'
Motivation: I'm using a software that doesn't have an API to interface with ... I have no alternative and have to open the software, send simple key sequence, then close ... Again and again, so I want to automate this process.
Goal: Send combinations of keyboard inputs to an inactive window.
Progress: I wrote a powershell script that open, send keys, wait, then end the process, but it only works on active window. A part of the powershell code is as follows.
$appProcess = Start-Process -FilePath $path -PassThru
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate($appProcess.Id)
$wshell.SendKeys('%(E)E')
Stop-Process $appProcess -Force
It works, but only on active window (windows comes to the top). What I want is to run automate the window in the background. I found an article that point me to using PostMessage in Win32 API. Since the majority of my code uses python, I decided to move from powershell to pywin32.
Issue: I cannot get the PostMessage to send key to the right handler. I saw in this article that I may need to find the exact window, but I still don't really understand how. In powershell, I can directly send keys via $wshell.AppActivate($appProcess.Id).
hwndMain = win32gui.FindWindow(None, winname)
hwndChild = win32gui.GetWindow(hwndMain, win32con.GW_CHILD)
temp = win32api.PostMessage(hwndChild, win32con.WM_KEYDOWN, 0x45, 0)
# temp came out as None
Question: Is there a way to do this in pywin32 / Win32 API?
Edit: (May 8, 2020) Yes, I have heard that using SendKeys are not reliable, but since there is no alternative offered to questions like this one on SO, how should anyone learn the "right way"? If you think there is alternative, everyone will appreciate to see a solution in action. Please suggest edits to my post to improve the quality of the question instead of shooting it down.
Time ago I developed SendMessage utility that allows to post messages to other processes or Windows via the WIN32 API. I discovered that I can't send a message to an inactive window, so I searched for a method to activate a Window. After several tests, I found a trick that allows me to "reactivate" a Window:
The development of this program presented a problem: the items in the
Notepad topmost menu can not be selected if the window was not active.
I did some tests and discovered that this point depends on the
relation that the cmd.exe window have (has?) with the other window and
the particular program in the other window. For example, in the case
of Calculator Windows accessory, its menu items can be selected when
the window is not active, and even when the window is minimized! I
tried to develop a method to activate other window from the cmd.exe
one using just System-Defined messages. I did several tests using
diverse combinations of WM_ACTIVATE, WM_CANCELMODE, WM_ENABLE,
WM_ACTIVATEAPP, WM_SETFOCUS and WM_KILLFOCUS messages, with no
success. Fortunately, the items in the system menu of any window can
be selected from another window, and after a SC_RESTORE the restored
window remains active; this behavior makes possible to activate
Notepad and other windows from the cmd.exe one via a Minimize/Restore
procedure.
I think that using my SendMessage.exe utility you may test if you may send keys to your inactive window process or to activate it, so you may then translate such a method to your phyton code. For complete details on this matter, see this link.
How to set a specific logon time for a specific user on Windows XP?
For example, the computer is an "always on machine" and most of the time no one is logged on. I want to set a time for my user to log on, without someone actually having to be in front of the machine. I've tried a workaround with the built-in auto logon function (control userpassword2), but I still need a secure system as I'm not the only user, and would still want a password even if I was the only user.
I have searched for third party software, but to no avail. I've a good knowledge of batch and Python scripting and a little of Java, so any pointers with any of those would help.
How can it be "secure" if it logs you on without you being there? Surely it would be better for it to wait for you to type in a password (i.e. the login prompt)?
If you want a fast "startup" time, then you can lock the workstation (ctrl+alt+del to open the Task Manager and then click 'Lock'. This shows a dialog just like the login prompt, but when you enter your password you instantly continue your existing session). Or if you want to be more eco friendly, put your PC into Sleep mode, which most PCs will return from (again with an optional password prompt) in less than 5 seconds.
One way I just thought of: Run a Vnc Server, and hack into an open source viewer program. Then you can rig it with some code to pass keyboard commands back into the computer, maybe implement some screen scraping to make sure it only does it when appropriate.
But seriously, there has to be a better way. Why are you trying to do this?
Logged into my Windows XP SP2 computer using my normal user account (which has Local Admin privileges), when I start the BDE Administrator -- either from the Control Panel or from the BDEADMIN.EXE directly -- I never get the GUI. It shows up on my task bar, and shows up in the Task Manager, but the GUI never appears. I can close the program by right-clicking on the task bar and choosing close. (note that "never" means not within 5 minutes of launching the program)
If I log into the same exact computer using a different user account (which also has Local Admin privileges), when I start the BDE Administrator, it loads the GUI within a couple seconds.
I used to be able to use the BDE Administrator while logged in under my normal user account, so it's not like this has always been a problem.
While this issue may not be directly programming related, it does make developing and testing a pain when I have to log off and back on a couple of times just to make changes to my BDE configuration.
I am totally stumped. Any idea what might be causing this odd behavior?
One idea is that you may have had two screens running on this box and dragged the window off screen.
Just search for the registry keys that control where the window opens up and delete them. Alternatively, you should be able to right click on the program in the task bar and select Move. Then use your arrow keys to bring it back.
Regardless, I'm voting to close.
I remember watching a webcast from Mark Russinovich showing the sequence of keyboard keys for a user initiated kernel dump. Can somebody refresh my memory on the exact order of the keys.
Please note this is for XP.
http://psacake.com/web/jr.asp contains full instructions, and here's an excerpt:
While it may seem odd to think about purposefully causing a Blue Screen Of Death (BSOD), Microsoft includes such a provision in Windows XP. This might come in handy for testing and troubleshooting your Startup And Recovery settings, Event logging, and for demonstration purposes.
Here's how to create a BSOD:
Launch the Registry Editor (Regedit.exe).
Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters.
Go to Edit, select New | DWORD Value and name the new value CrashOnCtrlScroll.
Double-click the CrashOnCtrlScroll DWORD Value, type 1 in the Value Data textbox, and click OK.
Close the Registry Editor and restart Windows XP.
When you want to cause a BSOD, press and hold down the [Ctrl] key on the right side of your keyboard, and then tap the [ScrollLock] key twice. Now you should see the BSOD.
If your system reboots instead of displaying the BSOD, you'll have to disable the Automatically
Restart setting in the System Properties dialog box. To do so, follow these steps:
Press [Windows]-Break.
Select the Advanced tab.
Click the Settings button in the Startup And Recovery panel.
Clear the Automatically Restart check box in the System Failure panel.
Click OK twice.
Here's how you remove the BSOD configuration:
Launch the Registry Editor (Regedit.exe).
Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters.
Select the CrashOnCtrlScroll value, pull down the Edit menu, and select the Delete command.
Close the Registry Editor and restart Windows XP.
Note: Editing the registry is risky, so make sure you have a verified backup before making any changes.
And I may be wrong in assuming you want BSOD, so this is a Microsoft Page showing how to capture kernel dumps:
https://web.archive.org/web/20151014034039/https://support.microsoft.com/fr-ma/kb/316450
As far as I know, the "Create Dump" command was only added to Task Manager in Vista. The only process I know of to do this is using the adplus VBScript that comes with Debugging Tools. Short of hooking into dbghelp and programmatically doing it yourself.
You can setup the user dump tool from Microsoft with hot keys to dump a process. However, this is a user process dump, not a kernel dump...
I don't know of any keyboard short cuts, but are you looking for like in task manager, when you right click on a process and select "Create Dump"?