Author: Armin Rigo <[email protected]>
Branch: release-2.2.x
Changeset: r67970:4a3ba24a561a
Date: 2013-11-12 12:42 +0100
http://bitbucket.org/pypy/pypy/changeset/4a3ba24a561a/

Log:    Add os.startfile() using cffi.

diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -27,6 +27,7 @@
             'popen2': 'app_posix.popen2',
             'popen3': 'app_posix.popen3',
             'popen4': 'app_posix.popen4',
+            'startfile': 'app_startfile.startfile',
         })
 
     if hasattr(os, 'wait'):
diff --git a/pypy/module/posix/app_startfile.py 
b/pypy/module/posix/app_startfile.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/posix/app_startfile.py
@@ -0,0 +1,44 @@
+
+class CFFIWrapper(object):
+    def __init__(self):
+        import cffi
+        ffi = cffi.FFI()
+        ffi.cdef("""
+        HINSTANCE ShellExecuteA(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT);
+        HINSTANCE ShellExecuteW(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT);
+        DWORD GetLastError(void);
+        """)
+        self.NULL = ffi.NULL
+        self.cast = ffi.cast
+        self.libK = ffi.dlopen("Kernel32.dll")
+        self.libS = ffi.dlopen("Shell32.dll")
+        self.SW_SHOWNORMAL = 1
+
+_cffi_wrapper = None
+
+
+def startfile(filepath, operation=None):
+    global _cffi_wrapper
+    if _cffi_wrapper is None:
+        _cffi_wrapper = CFFIWrapper()
+    w = _cffi_wrapper
+    #
+    if operation is None:
+        operation = w.NULL
+    if isinstance(filepath, str):
+        if isinstance(operation, unicode):
+            operation = operation.encode("ascii")
+        rc = w.libS.ShellExecuteA(w.NULL, operation, filepath,
+                                  w.NULL, w.NULL, w.SW_SHOWNORMAL)
+    elif isinstance(filepath, unicode):
+        if isinstance(operation, str):
+            operation = operation.decode("ascii")
+        rc = w.libS.ShellExecuteW(w.NULL, operation, filepath,
+                                  w.NULL, w.NULL, w.SW_SHOWNORMAL)
+    else:
+        raise TypeError("argument 1 must be str or unicode")
+    rc = int(w.cast("uintptr_t", rc))
+    if rc <= 32:
+        # sorry, no way to get the error message in less than one page of code
+        code = w.libK.GetLastError()
+        raise WindowsError(code, "Error %s" % code, filepath)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to