How can I make a health check of a window by hwnd? Simply put, I need to handle an error if it happens.
The mistake in question:
I assume this can be done with Win32 libraries, but my searches haven't led to anything.
Use SendMessageTimeout() to send the HWND a benign message, like WM_NULL. You can specify whether the function should fail if a timeout elapses, or even fail immediately if the window's thread is hung (not processing messages).
Related
The short of it is that I am trying to add a keybinding to my program that will edit the clipboard and then paste the changes to whatever window you have active. On Windows I think I can probably do it with message passing, but X doesn't use message passing like that, so in order to do this, I'm just using python-evdev to send a ctrl+v event to uinput. This works reasonably well when you just run it, but I need it to run on a keybinding, in this case super+v. The problem becomes that when you send the ctrl and v events to uinput, the super mask is still active, so instead of send ctrl+v to the window, it sends ctrl+super+v, which doesn't actually do anything. Here's minimal code to explain exactly what i'm talking about:
import evdev,time,keybinder,gtk
def callback():
with evdev.UInput() as uinput:
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 1)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 1)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 0)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 0)
uinput.syn()
keybinder.bind("<super>v",callback)
keybinder.bind("Escape",gtk.main_quit)
gtk.main()
If you release super quickly enough you can actually get it to work, but it's pretty fast and obviously not acceptable for an actual application. I've tried to release super but that raises a few problems; it's not very generic, it raises the problem of what to do afterwards (Leave it released? Press it again? What if they released within the time between you releasing and then pressing it again?), and, most importantly, it doesn't really seem to work.
Anyways, I guess the question is, is there any way around this? Perhaps a way to send keypress events that won't combine with the physical keyboard(unlikely)? If not, is there any better way to get it to paste generically on Linux?
I don't think this has a solution. As you clearly already understand, Ctrl-V is not an IPC mechanism used to initiate a "paste" operation, it's just a common keybinding to do that (note that your trick won't work if you happen to have emacs running in the foreground, where your gadget will just scroll the window up by a page). And I think you're right, there are no standards (e.g. something at freedesktop.org) to ask a window to "paste right now", nor really should there be.
At least as commonly understood and implemented by apps, paste is a user-initiated action. No app is going to expect it to be driven by an external tool. What's the actual problem you're trying to solve? Can't you bind something to run in your client apps or maybe hook an accessibility/input method framework instead?
That said: I think you have the right approach if you want to make this particular hack work. Query they keymap at the start of the operation, clear the state of any modifier keys, send your events, then reset the state. You still have an unsolvable race vs. the hardware keyboard obviously, but I suspect in practice that won't be a huge problem.
You need to find a way to ascertain if the <super> key is currently held down.
In wxpython that would be Super = wx.GetKeyState(wx.WXK_META), I don't know what that would be in Gtk.
Then your code would be as follows:
def callback():
Super = wx.GetKeyState(wx.WXK_META) # Here you require the Gtk equivalent
with evdev.UInput() as uinput:
if Super:
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 0)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 1)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 1)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 0)
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 0)
if Super:
uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 1)
uinput.syn()
As you can see, you were within a gnat's tadger of getting it.
The added code, simply turns the Super key off before your required Ctrl+v and then back on again, afterwards.
I'd like to know how to have a program wait for another program to finish a task. I'm not sure what I'd look for for that...
Also, I'm using a mac.
I'd like to use Python or perhaps even applescript (I could just osascript python if the solution if for applescript anyway)
Basically this program "MPEGstreamclip" converts videos, and it opens what appears to be 2 new windows while it's converting. One window is a conversion progress bar, and the other window is a preview of the conversion. (Not sure if these actually count as windows)
(Also, MPEGstreamclip does not have an applescript dictionary, so as far as I know, it can't listen for certain window names existence)
But basically I want my program to listen for when MPEGstreamclip is done, and then run its tasks.
If it helps, when the conversion is done, the mpegstreamclip icon in the dock bounces once. I'm not sure what that means but I'd think you could use that to trigger something couldn't you?
Thanks!
I realized GUI applescript was the answer in this scenario. With it I could tell the PROCESS to get every window, and that worked. However, I'm leaving this up because I'd like to know other ways. I'm sure this GUI workaround won't work for everything.
If the MPEGstreamclip actually ends when it is done, you could wrap the whole thing up in a python script using various techniques already discussed in another post. Just be sure to wait for the external process to end before continuing with your other steps.
There seems to be a distinct lack of documentation of the GObjects module for python at the moment, so maybe somebody can help me.
I am making an application which occasionally will have to notify the user that an event has occurred. I have found about using from gi.repository import Notify and the relating classes from using a short snippet for skype notifications and the C documentation, but it seems to not close when I call Notify.uninit. The program closes, but the little notification window thing stays put and has to be closed by right clicking on it and selecting "Remove". So, I am wondering if there is perhaps another way like if there was something similar to how in Mac OS the application icon shakes/bounces when something happens or in Windows the application icon glowing a different color?
I like the Gnome 3 notification system with the message stack and such, but since I can't seem to get it to disappear when my application exits I don't really want to use it (unless someone knows how to properly do this...it may be that I forgot to set a timeout, but that still doesn't make sense as to why I can't just make the notification spot disappear).
Calling Notify.uninit is not supposed to make the notifications disappear, it only tells libnotify that it will no longer be needed for your application. To make notifications disappear, you have to close them explicitly like in the following example:
import time
from gi.repository import Notify
Notify.init('myapp')
# optionally set an icon as the last argument
n = Notify.Notification.new('summary text', 'body text', "dialog-information")
n.show()
# do whatever your application is doing
time.sleep(10)
n.close()
Notify.uninit()
I am looking for a means to kill a Windows exe program that, when being tested from a python script, crashes and presents a dialog to the user; as this program is invoked many times, and may crash repeatedly, this is not suitable.
The problem dialog is the standard reporting of a Windows error:
"Foo.exe has encountered a problem and needs to close. We are sorry for the inconvenience"
and offers a Debug, Send Error Report, and Don't Send buttons.
I am able to kill other forms of dialog resulting from crashes (e.g. a Debug build's assert failure dialog is OK.)
I have tried taskkill.exe, pskill, and the terminate() function on the Popen object from the subprocess module that was used to invoke the .exe
Has anyone encountered this specific issue, and found a resolution?
I expect automating user input to select the window, and press the "Don't Send" button is one possible solution, but I would like something far simpler if possible
Wouldn't it be easier to disable the error reporting feature?
If you were to use CreateProcessEx or a WinAPI specific function, you might be able to call TerminateProcess or TerminateThread to forcibly end the process.
I have complex GUI application written in Python and wxPython.
I want it to be certified for Windows Vista, so it has to crash in a way that causes Windows Error Reporting dialog (The one that asks "Do you want to send report to Microsoft?") to appear. This is relevant to test case no 32 from "Certified for Windows Vista Test Cases" document.
Unfortunately when I crash my app with ThreadHijacker tool wxPython shows message like:
Unhandled exception
---------------------------
An unhandled exception occurred. Press "Abort" to terminate the program,
"Retry" to exit the program normally and "Ignore" to try to continue.
---------------------------
Abort Retry Ignore
How can I prevent wxPython from showing this message? I have custom sys.excepthook, but it seems that this dialog is shown before my except hook can interfere.
EDIT:
wxWidgets docs says that wxAppConsole::OnExceptionInMainLoop is called and under MSW it displays some fancy dialog that allows user to choose between the different options. It seems however, that wxPython doesn't allow overloading that function... Does anyone know how to change default behaviour of wxAppConsole::OnExceptionInMainLoop in wxPython?
I prefer solutions that are on Python level over those that go into C/C++
EDIT2:
All in all, I asked at wxPython mailing list, and Robin Dunn answered that he'll look into making wxAppConsole::OnExceptionInMainLoop overridable in next releases of wxPython. Since I couldn't wait, I had to compile my own version of wxPython which does not include that function. It turned out that the presence of wxAppConsole::OnExceptionInMainLoop function can be enabled/disabled by proper setting of compilation flags.
It all ended up with compiling my own wxWidgets and wxPython, with just one compilation flag changed: wxUSE_EXCEPTIONS should be set to 0.
Robin Dunn wrote that he will try to patch wxPython, so this behaviour could be modified without recompiling of the whole library.
If I remember correctly, this is a catch(...) at top level (wxApp) in wxWidgets. You can either use a vectored Exception Handler or _set_se_translator() to get a first shot at the Structured Exception, and exit to WER, i.e. ReportFault() from there.
Is it possible for you to just handle everything? You would have to, I guess, put a try:except: block around every method bound to a widget. You could write a decorator:
def catch_exception(f):
def safe(*args, **kw):
try:
f(*args, **kw)
except Exception, e:
handle_exception(e)
return safe
def handle_exception(e):
# do Vista stuff
sys.exit()
Then decorate any function that could be called by the mainloop (since I presume that's where wxPython does its own catching).
Try http://wiki.python.org/moin/CrashingPython