I have dabbled around for a year or so using c++ and decided I would try my hand at python as it has a much easier syntax and will increase productivity while I am still learning (I think!). I am trying to enumerate all child windows from a parent window of a desktop application in Windows.
import win32ui
def WindowExists(windowname):
try:
win32ui.FindWindow(None, windowname)
except win32ui.error:
return False
else:
return True
appFind = "Test Application"
if WindowExists(appFind):
print ("Program is running")
hwnd = win32ui.FindWindow(None, appFind)
else:
print ("Program is not running")
So far I am identifying the application with no problem but I am wondering if my assignment of hwnd is working as I think it would do in a c++ environment so I would be able to pass my hwnd assignment to enumchildwindows. I am not entirely sure how I get the children from here though.
One other question I had was rather than using just the title of the application, how can I use the handle? if for example the handle was something like 00130903 of testapplication. I remember a few months I messed around with something like this in c++ and I think you can use x to replace the first set of zeros (or something similar) on the handle, but I honestly cant remember much of it so hopefully you guys can help!
Edit -
TypeError: The object is not a PyHANDLE object.
I think my assumption is right here that I am not correctly assigning a proper handle named hwnd , this is the error i get when I try to use enumchldwindows or win32con.WM_GETTEXT , any example of correctly setting a handle by title and by handle would really be appreciated!
hwnd = win32ui.FindWindow(None, appFind) , worked for verifying the windows existance
hwnd = win32gui.FindWindow(None, appFind), worked to allow me to use the handle!, live and we learn!
Related
I'm writing a Python script to toggle the "Hidden Items" status of the Windows Explorer. It changes the value of Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Hidden, but for the change to take effect all instances of the Explorer have to be refreshed.
I implemented the same idea a few months ago with AutoHotkey, there I could solve the refresh problem with the following commands I found on the AutoHotkey Forum:
WinGetClass, CabinetWClass
PostMessage, 0x111, 28931, , , A
PostMessage, 0x111, 41504, , , A
I tried different approaches to translate it, but wasn't able to get it working with Python. While searching for an answer I also found a solution with C# (Refresh Windows Explorer in Win7), which is far more complicated than the AutoHotkey version. I could let the Python script call the C# script, but I would much prefer a solution without auxiliary files.
How can I implement such behavior with Python?
Using pywin module:
import win32con
import win32gui
# List for handles:
handles = []
def collect_handles(h, _):
' Get window class name and add it to list '
if win32gui.GetClassName(h) == 'CabinetWClass':
handles.append(h)
def refresh_window(h):
' Send messages to window '
win32gui.PostMessage(h, win32con.WM_COMMAND, 28931, None)
win32gui.PostMessage(h, win32con.WM_COMMAND, 41504, None)
# Fill our list:
win32gui.EnumWindows(collect_handles, None)
# Perform action on our handles:
list(map(refresh_window, handles))
I want to be able to detect the presence of a specifically named window (in any process) to use as an "if" variable
After some research, I've concluded I must use the win32gui library (some posts also suggest ctypes), but most of the posts I find are about making a list of processes, and the only one that was related to this topic didn't answer the question properly. Perhaps I am too novice to understand it, but at last, I couldn't get it to work (the question was this one)
To exemplify what I want, I'll share a simple .vbs code that does that: It searches for a specific name (in our case, steve jobs) and if it finds it anywhere, it triggers (in this example, it closes said process)
do
WindowTitle = "steve jobs"
set shell = createObject("wscript.shell")
success = shell.appactivate(WindowTitle)
if success then shell.sendkeys "%{F4}"
loop
import win32gui
win2find = input('enter name of window to find')
whnd = win32gui.FindWindowEx(None, None, None, win2find)
if not (whnd == 0):
print('FOUND!')
You can search Google for 'FindWindowEx'
to find https://msdn.microsoft.com/en-us/library/windows/desktop/ms633500(v=vs.85).aspx
for a description of the FindWindowEx function
bmp = wx.Image("C:\User\Desktop\cool.bmp", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
If i run this, it will automatically show an error message saying that it failed to load the image. How can I stop my program from doing this?
If all you're after is to stop the exception from raising, you can enclose it in a try/except block:
try:
bmp = wx.Image("C:\User\Desktop\cool.py", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
except:
pass
Bear in mind, it's good practice to only ignore specific exceptions, and to do something when it occurs (ie tell user to pick another image):
try:
bmp = wx.Image("C:\User\Desktop\cool.py", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
except <Specific Exception>, e:
doSomething() # Handle exception
Since it's an actual pop up message, you can use wx.Log_EnableLogging(False) to disable error logging in your application
To stop stderr redirecting you can set wx.App(redirect=False)
Or to make error log to a file instead of onscreen you can use:
wx.App(redirect=True,filename='error_log')
For wxpython version 4+, I was able to disable the popup message by calling
wx.Log.EnableLogging(False)
or by calling
wx.Log.SetLogLevel(wx.LOG_Error)
Relevant docs here
An alternative to wx.Log_EnableLogging(False) is wx.LogNull. From the docs:
# There will normally be a log message if a non-existent file is
# loaded into a wx.Bitmap. It can be suppressed with wx.LogNull
noLog = wx.LogNull()
bmp = wx.Bitmap('bogus.png')
# when noLog is destroyed the old log sink is restored
del noLog
I can't even get my wxPython code to run if I pass it an an invalid image. This is probably related to the fact that wxPython is a light wrapper around a C++ library though. See http://wiki.wxpython.org/C%2B%2B%20%26%20Python%20Sandwich for an interesting explanation.
The best way around issues like this is to actually use Python's os module, like this:
if os.path.exists(path):
# then create the widget
I do this sort of thing for config files and other things. If the file doesn't exist, I either create it myself or don't create the widget or I show a message so I know to fix it.
Just as the title says. I want to write a script that behaves differently depending on whether it's running inside a console window or in IDLE. Is there an object that exists only when running in IDLE that I can check for? An environment variable?
I'm using Python 2.6.5 and 2.7 on Windows.
Edit:
The answers given so far work. But I'm looking for an official way to do this, or one that doesn't look like a hack. If someone comes up with one, I'll accept that as the answer. Otherwise, in a few days, I'll accept the earliest answer.
I would prefer to do:
import sys
print('Running IDLE' if 'idlelib.run' in sys.modules else 'Out of IDLE')
Google found me this forum post from 2003. With Python 3.1 (for win32) and the version of IDLE it comes with, len(sys.modules) os 47 in the command line but 122 in the IDLE shell.
But why do you need to care anyway? Tkinter code has some annoyances when run with IDLE (since the latter uses tkinter itself), but otherwise I think I'm safe to assume you shouldn't have to care.
I suggest packing all the code in one function (Python 3):
def RunningIntoPythonIDLE():
import idlelib.PyShell
def frames(frame = sys._getframe()):
_frame = frame
while _frame :
yield _frame
_frame = _frame.f_back
return idlelib.PyShell.main.__code__ in [frame.f_code for frame in frames()]
So tkinter apps can do its check:
if not RunningIntoPythonIDLE():
root.mainloop()
I'm a touch late, but since IDLE replaces the standard streams with custom objects (and that is documented), those can be checked to determine whether a script is running in IDLE:
import sys
def in_idle():
try:
return sys.stdin.__module__.startswith('idlelib')
except AttributeError:
return True
My suggestion is to get list of all running frames and check if main Idle method would be in there.
def frames(frame = sys._getframe()):
_frame = frame
while _frame :
yield _frame
_frame = _frame.f_back
import idlelib.PyShell
print(idlelib.PyShell.main.func_code in [frame.f_code for frame in frames()])
the frames function generates frames running at moment of its declaration, so you can check if idle were here.
I'm trying to find an equivalent Python function to the Windows function DriveInfo.IsReady. I've spent a while searching through the functions provided by win32api and win32file but I can't find anything (though perhaps that's because I didn't manage to find much useful documentation online, so was simply searching through the listing of functions).
Any help would be gratefully received.
I've used GetVolumeInformation in the past to determine this. For example, something like:
def is_drive_ready(drive_name):
try:
win32api.GetVolumeInformation(drive_name)
return True
except:
return False
print 'ready:', is_drive_ready('c:\\') # true
print 'ready:', is_drive_ready('d:\\') # false (on my system)
You'll need the win32api module.