How to Use Win32 API with Python

How to use Win32 API with Python?

PyWin32 is the way to go - but how to use it? One approach is to begin with a concrete problem you're having and attempting to solve it. PyWin32 provides bindings for the Win32 API functions for which there are many, and you really have to pick a specific goal first.

In my Python 2.5 installation (ActiveState on Windows) the win32 package has a Demos folder packed with sample code of various parts of the library.

For example, here's CopyFileEx.py:

import win32file, win32api
import os

def ProgressRoutine(TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred,
StreamNumber, CallbackReason, SourceFile, DestinationFile, Data):
print Data
print TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred, StreamNumber, CallbackReason, SourceFile, DestinationFile
##if TotalBytesTransferred > 100000:
## return win32file.PROGRESS_STOP
return win32file.PROGRESS_CONTINUE

temp_dir=win32api.GetTempPath()
fsrc=win32api.GetTempFileName(temp_dir,'cfe')[0]
fdst=win32api.GetTempFileName(temp_dir,'cfe')[0]
print fsrc, fdst

f=open(fsrc,'w')
f.write('xxxxxxxxxxxxxxxx\n'*32768)
f.close()
## add a couple of extra data streams
f=open(fsrc+':stream_y','w')
f.write('yyyyyyyyyyyyyyyy\n'*32768)
f.close()
f=open(fsrc+':stream_z','w')
f.write('zzzzzzzzzzzzzzzz\n'*32768)
f.close()

operation_desc='Copying '+fsrc+' to '+fdst
win32file.CopyFileEx(fsrc, fdst, ProgressRoutine, operation_desc, False, win32file.COPY_FILE_RESTARTABLE)

It shows how to use the CopyFileEx function with a few others (such as GetTempPath and GetTempFileName). From this example you can get a "general feel" of how to work with this library.

How should I learn to use the Windows API with Python?

Honestly, no. The Windows API is an 800 pound monster covered with hair. Charlie Petzold's 15 pound book was the canonical reference once upon a time.

That said, the Python for Windows folks have some good material. Microsoft has the whole API online, including some sample code and such. And the Wikipedia article is a good overview.

Where to find the win32api module for Python?

'pywin32' is its canonical name.

http://sourceforge.net/projects/pywin32/

Windows device file does not return valid handle with python win32API

The API should not return zero. It should return a PyHANDLE object. I don't have your device, but opening an existing file works. The 3rd parameter should be w32.FILE_SHARE_READ (or similar share mode value), however:

>>> import win32file as w32
>>> w32.CreateFile('blah.txt',w32.GENERIC_READ,w32.FILE_SHARE_READ,None,w32.OPEN_EXISTING,w32.FILE_ATTRIBUTE_READONLY,None)
<PyHANDLE:280>

If the file does not exist (or any other error), Python should raise an exception based on the GetLastError() code returned by the Win32 API called:

>>> w32.CreateFile('blah.txt',w32.GENERIC_READ,w32.FILE_SHARE_READ,None,w32.OPEN_EXISTING,w32.FILE_ATTRIBUTE_READONLY,None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pywintypes.error: (2, 'CreateFile', 'The system cannot find the file specified.')

If this doesn't help, edit your question to show the exact code you are running and the exact results of running the code.

Using Win32 api from python

The problem with your program isn't about the win32api. It fails because whenever you call any OS function (os.remove, win32api.SetFileAttributes) you pass only partial name (that is, the portion after the 'path'.
change the first line of your function to:

def del_dir(path):
for file_or_dir in os.listdir(path):

change to:

def del_dir(path):
for x in os.listdir(path):
file_or_dir = os.path.join(path,x)

the rest is the same. By the way, this is really a bad sample to delete entire directory, or to recursively walk a folder hierarchy. Use os.walk for a simple code.

In general, win32api and win32con working just fine. Open a python shell and try this much simpler code:

>>> import win32api
>>> import win32con
>>> win32api.MessageBox(0, "hello win32api", "win32api", win32con.MB_OK)

Windows: iterate on a file in python using Win32API

The problem is that the objects handle and file_descriptor might get garbage collected after the function open returns.
When you call __next__ the objects might have been freed which raises the OSError: [Errno 9] Bad file descriptor. That's also why it works when you read the file in the open function itself, because there the objects are still present.

To solve this simply store the objects as instance attributes so there is at least one reference to them.

def open(...)
...
self.handle = CreateFile(...)
...
self.file_descriptor = msvcrt.open_osfhandle(self.handle, ...)
...
self.fh = open(self.file_descriptor, ...)
...

It might be sufficient to only store one of them but I am not sure which one. Storing both is the save way.

Python 3.6 install win32api?

Information provided by @Gord

Since September 2019 pywin32 should be installed via PyPI which ensures that the latest version (currently version 304) is installed. This is done via the pip command

pip install pywin32

If you wish to get an older version the sourceforge link below would probably have the desired version, if not you can use the command, where xxx is the version you require, e.g. 300

pip install pywin32==xxx

This differs to the pip command in another comment and in an old edit of this answer in that pypiwin32 installs an outdated version (namely 223)

Browsing the docs I see no reason for these commands to not work for all python3.x versions, I am unsure on python2.7 and below so you would have to try them and if they do not work then the solutions below will work.


Probably now undesirable solutions but certainly still valid as of September 2019

There is no version of specific version ofwin32api. You have to get the pywin32module which currently cannot be installed via pip. It is only available from this link at the moment.

https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/

The install does not take long and it pretty much all done for you. Just make sure to get the right version of it depending on your python version :)


Also it can be installed from this GitHub repository as provided in comments by @Heath



Related Topics



Leave a reply



Submit