I need to run a lengthy set of unit tests quite often each day, and as part of the tests, some windows pop up and are subsequently closed by the test script. Ideally, I'd like to continue working while the tests are running, so I'd need to stop the testing software from taking focus or opening a window in front of what I'm currently working on.
Is there a way to stop descendants of a certain process from taking focus when opening a window and from opening a window at the top of the z-order, or can I redirect the windows to another screen where they don't bother me?
You can create another user account, run your tests in your current user account, and just switch to another user account to do what you want.
But if you have a PC with low GH and RAM then I don't recommend you do that.
Related
I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.
Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.
The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!
This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.
How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.
The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.
No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.
In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.
For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.
See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.
There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.
I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.
It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.
On Microsoft Windows (8), I would like to start a process, and prevent it from showing any windows at all. Alternatively, to force-close any windows that are shown. Is there a way to do this?
My application is this: I'm running an automated (nunit) test suite on my continuous integration (teamcity) server. The code under test is also used by an interactive application. Developers occasionally slip in a dialog with a user prompt, without realising what they are doing. This causes the CI process to stop, waiting for user input which never comes. I'd like to be able to dismiss any dialog that appears, or prevent them from being shown.
Even better would be to force an exception at this point, so that the test would also fail.
In my case, this is a C# application, and the dialogs shown are Windows Forms or WPF dialogs.
I did find a couple of similar questions. However each turned out to be solving a slightly different problem.
Stop a process from showing a window from C# (solves a different problem)
Preventing blocking dialogs/message boxes/hanging GUI from non-interactive processes on Windows? (promising solution but C++-specific)
Prevent child process from creating visible windows? (solves a different problem)
Have you considered asking your development team to have a "no dialog" mode of the app for testing purposes? Perhaps if you stopped referring to them as (!!*&%) they would be more inclined to partner with you. ;) Afterall, you do work at the same company on the same product :)
In any case, without a dev-specific solution, consider having a another app (process or thread) that continually sleeps for a few seconds, wakes up and looks for a modal dialog in your application. You can use APIs such as FindWindow to identify when a modal dialog has popped up. (Use Spy++ to get the class name for windows created by MessageBox and CreateDialog APIs).
I have a Cocoa application which I am running as an agent because it has a status bar component. When my application brings up a window, these windows don't appear in the list when I press Ctrl-Tab to cycle through applications.
Is there a way to force a window in my application to appear?
Not while it's an agent, because it can never become the active application. Agents are meant to have only minimal user interaction, so it's assumed that you won't have an agent window around long enough for the user to need to command-tab away from it. (I personally find this annoying, because I'm constantly losing crash report windows behind application windows for the same reason, but it does make sense.)
However, the app doesn't have to be running as an agent in order for the status bar item to work, so I would just set the LSUIElement flag to NO and be done with it. It can be a regular, non-agent app that just happens to instantiate a status bar item.
If you don't want the application to be able to become active except when a window is visible, then that's more involved. You'd probably need to separate the application and the agent into separate processes, and have the agent launch the application in order to display the window. Then make sure the application quits when the window is closed, leaving just the agent running. Arq (http://www.haystacksoftware.com/arq/) is one example of an app/agent pair that works this way, with perhaps a clearer distinction between the agent and the app than you're after.
I have been working on windows automation and monitoring.
What exactly happens when I lock the screen of a windows machine?
I am working with Windows 7 at the moment, are there big differences to the behavior if I switch to Vista or the server versions?
Is there still a desktop that can be accessed via api's?
I know that i can still send key strokes and mouse clicks to specific windows (via ControlSend and ControlClick), but there seems to be no "desktop" itself.
Could someone shed some light on this whole thing or point me at a readable source where I could get an overview over the topic?
Basically what happens is that Windows switches to the secure desktop, makes it the current one, so input is now associated with it.
The old desktop remains where it was: all the HWNDs on the desktop are still there, and any thread attached to that desktop can still access those HWNDs, get their location, and so on. You can still send messages to windows on this desktop, so long as the thread sending the message is also on that desktop.
However, since the desktop is now inactive, it cannot receive input. GetForegroundWindow will return NULL (IIRC), and you can't use SendInput any longer, since input now belongs to [a thread on] a different desktop; no controls on that inactive desktop can receive focus.
Note that sending keypress messages to a control that doesn't have focus can sometimes cause unexpected behavior, since the app or control generally never expects to receive keyboard input without getting the focus first. (This can be problematic for controls that set up some sort of input context in WM_SETFOCUS and clear it up in WM_KILLFOCUS, for example.)
In short, the UI is still there: you can do certain queries against it, but you can no longer automate it as you could on a regular desktop by sending input, and some other functions that relate to focus or input may fail.
I'm not super familiar with AutoHotKey, but the name and description of functionality suggests that it's heavily reliant on the underlying Win32 SendInput API. This won't work at all for keyboard input when a desktop is inactive.
For a reasonable overview of how desktops work and how they relate to winstations, the locked desktop, and so on, check out the Desktop article on MSDN.
One issue that I've run into in the past with desktops and automation is: how to I leave a long-running test that's using some form of user input automation (mouse, keyboard simulation), but still lock my PC so that someone can't just walk by and interfere with it. Once you lock the PC, the desktop is inactive, and so the automation stops working. A similar issue happens if the screensaver kicks in: the desktop switches, and the automation fails.
One solution is to use two PCs: let's call them Main and Test: from Main, open a remote terminal services client onto the Test machine, and then run the automated test on the test machine, but from a terminal services client window on the Main machine. Now the cool part: you can minimize that TSC window, or even lock the Main machine (or let the screensaver kick in), and that virtual session will continue working, thinking that it is still active - it's just that nobody is paying it any attention. This is one way to create a "connected" session with an active desktop, but one that no-one can interfere with, because it's protected behind the locked desktop of the Main machine.
I don't know the details, but I believe the lock screen constitutes a separate "desktop" and maybe also a separate "window station" (as I understand it a window station is merely a container for desktops). The MSDN section on window stations should hopefully be useful: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687098%28v=vs.85%29.aspx
In order to access a desktop, you will need to use the regular windows api's from a thread that is on that desktop. SetThreadDesktop would probably be the easiest way to do that in C, as long as the desktop isn't on a different window station.
Unfortunately, this is already difficult for a regular privileged application, and using AutoHotkey complicates it even more. Since you don't have control over threads or over process initialization, you will probably have to create a new process in the other desktop (you can do this using the CreateProcess API, which appears to have a wrapper available for AHK to which you can supply a desktop name: http://www.autohotkey.com/forum/topic1952.html). Your process will need special privileges to do this; I'm not sure that even running as Administrator is enough.
I'm trying to make an simple anti-idle script (that moves the mouse or whatever) to prevent an application from stopping.
How can I keep it running after screen lock ?
It seems like this is explained in the Autoit faq :
http://www.autoitscript.com/wiki/FAQ#Why_doesn.27t_my_script_work_on_a_locked_workstation.3F
On locked station any window will never be active (active is only dialog with text "Press Ctrl+Alt+Del") In Windows locked state applications runs hidden (behind that visible dialog) and haven't focus and active status.
So generally don't use Send() MouseClick() WinActivate() WinWaitActive() WinActive() etc.
Instead use ControlSend() ControlSetText() ControlClick() WinWait() WinExists() WinMenuSelectItem() etc. This way you may have your script resistive against another active windows. It's possible to run such script from scheduler on locked Windows station.
You can't automate anything after your screen is locked. User input is simply ignored. A much easier way would be to prevent your screen from locking, for example, by moving the mouse randomly every 30 seconds.