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.
Related
I noticed the following gem in python's source code for ntpath..
def islink(path):
"""Test for symbolic link.
On WindowsNT/95 and OS/2 always returns false
"""
return False
This obviosly isn't the case for vista beyond. So, whenever python encounters a windows symbolic link, it always says that it isn't. To make things more interesting,
x = os.stat(symbolic_link_name)
x.st_mode
16895
import stat
stat.S_ISLNK(x.st_mode)
False
Which means stat it's self does not record the ordinals/flags which indicate that the file is a symbolic link. I would like to fix this or at least point this out to developers, but for the life of me, I can't find the source code for where os.stat() is being compiled from.
Where do I go to edit this source code?
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!
I am using Python2.7. When I enter help(), and enter "modules", I get the message
>>> help()
Welcome to Python 2.7! This is the online help utility.
...
help> modules
Please wait a moment while I gather a list of all available modules...
Then I get a series of warnings
Warning: cannot register existing type 'GtkWidget'
...
Warning: cannot add class private field to invalid type '<invalid>'
...
Then the whole thing hangs... to the point where I had to start a second remote session to send a SIGKILL.
obviously something is wrong, but what I was most surprised by was the bit where it reaches out to the web to gather information.
Isn't Python's help documentation available stored locally? How do I stop it from going out to the web? I want regular help, not online help.
The help() command does not search on the internet; the "online" simply means that you can use it interactively, in the documentation it calls it "built-in help system" which is less amiguous. What it does it traverses all the PYTHONPATH and tries to import every module in order to see which are the available modules in your system.
Here's the source code that is used to obtain the list of module(you can find in under Lib/pydoc.py in the python sources):
def listmodules(self, key=''):
if key:
self.output.write('''
Here is a list of matching modules. Enter any module name to get more help.
''')
apropos(key)
else:
self.output.write('''
Please wait a moment while I gather a list of all available modules...
''')
modules = {}
def callback(path, modname, desc, modules=modules):
if modname and modname[-9:] == '.__init__':
modname = modname[:-9] + ' (package)'
if modname.find('.') < 0:
modules[modname] = 1
def onerror(modname):
callback(None, modname, None)
ModuleScanner().run(callback, onerror=onerror)
self.list(modules.keys())
self.output.write('''
Enter any module name to get more help. Or, type "modules spam" to search
for modules whose descriptions contain the word "spam".
''')
Where the ModuleScanner class simply traverses built-in modules, and the modules that pkgutil.walk_packages finds, this function in the ends calls the iter_modules method of the importer objects. The built-in importer does not support importing modules from the internet, hence the internet is not searched. If you install custom importers than help() may trigger an internet research.
If you have a lot of modules available then this operation may take some time. Some modules may also take significant time to import(e.g. numpy, scipy etc may take in the order of seconds to load).
On console export PYTHONDOCS=/usr/share/doc/python2/html/ to determine where python should search help.
I am having a problem with calling GetModuleHandleA() using Python. I have a module that attaches as debugger to the process. I'm working on a function that would return address of the function in the specific DLL module. GetModuleHandleA("msvcr100") fails all of the time.
from ctypes import *
kernel32 = windll.kernel32
Function declared as part of a bigger debug class. That's the part of function declaration:
def resolve_function(self,dll,function):
handle = kernel32.GetModuleHandleA(dll)
if handle == False:
print "kernel32.GetModuleNameA() failed!!!"
return False
address = kernel32.GetProcAddress(handle, function)
if address == False:
print "kernel32.GetProcAddress() failed!!!"
return False
kernel32.CloseHandle(handle)
return address
Call the function made as:
function_address = debug.resolve_function("msvcr100", "printf")
I run separate process that uses printf() and then attach to it. Everything works fine until I get to GetModuleHandleA() that returns False all of the time.
Code that runs printf():
from ctypes import *
import time
msvcr100 = cdll.msvcr100
counter = 0
while 1:
msvcr100.printf("Counter = %d\n" % counter)
time.sleep(1)
counter += 1
Any ideas?
You've found the solution to your problem, but I'm answering anyway to explain why your original effort failed (and why your fix worked).
First, msvcrt/msvcr100 are two different versions of Microsoft's C runtime library. There are other versions as well, and all of them contain their own definitions for printf(). A given process may have any one of them loaded, or multiple versions loaded, or no versions loaded - it's possible to produce console output using only WinAPI functions! In short, if it's not your process, you can't depend on any given version of the C runtime being available.
Second, GetModuleHandle() doesn't load anything. It returns a handle to the named module only if it has already been loaded. msvcr100.dll can be sitting right there on disk, but if the process hasn't already loaded it then GetModuleHandle won't give a handle to you. LoadLibrary() is the function you'd call if you wanted to both load and retrieve a handle to a named module... But you probably don't want to do this in a process you don't own.
FWIW, Process Explorer is a handy tool for viewing the DLLs already loaded by a process.
After modifying:
...
handle = kernel32.GetModuleHandleA(dll)
if handle == False:
error = GetLastError()
print "ERROR: %d - %s" % (error, FormatError(error))
return False
...
I get: ERROR: 126 - The specified module could not be found
I actually replaced msvcr100.dll with msvcrt.dll in my code and it worked perfect. I found out that msvcrt.dll is system dll. msvcr100.dll ships with Studio 2010. They are both located in C:\Windows\system32. It is still a mystery for me why msvcr100.dll did not work.
Use GetLastError() (or WinError) from ctypes to find out why you're getting a NULL return, then add that information to your error message. Even after you figure out this specific problem, you'll want that more robust error reporting.
See the ctypes docs for details: http://docs.python.org/library/ctypes.html
Try calling:
msvcr100 = cdll.msvcr100
before calling:
function_address = debug.resolve_function("msvcr100", "printf")
to make sure the DLL is loaded in your process. msvcrt might work because it was already loaded.
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.