From 899a3efeb3989d0b15288596ba85cce372d6b8a0 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 17 Oct 2010 18:00:56 +0100 Subject: [PATCH] Converted the compiled win module to ctypes. --HG-- branch : py3k --- modules/send2trash_win.c | 81 ---------------------------------------- send2trash/plat_win.py | 44 +++++++++++++++++++++- setup.py | 11 ------ 3 files changed, 42 insertions(+), 94 deletions(-) delete mode 100644 modules/send2trash_win.c diff --git a/modules/send2trash_win.c b/modules/send2trash_win.c deleted file mode 100644 index c9e8a31..0000000 --- a/modules/send2trash_win.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2010 Hardcoded Software (http://www.hardcoded.net) - -This software is licensed under the "BSD" License as described in the "LICENSE" file, -which should be included with this package. The terms are also available at -http://www.hardcoded.net/licenses/bsd_license -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" - -#define WINDOWS_LEAN_AND_MEAN -#include "windows.h" -#include "shlobj.h" - -/* WARNING: If the filepath is not fully qualified, Windows deletes the file - rather than sending it to trash. - */ - -static PyObject* send2trash_win_send(PyObject *self, PyObject *args) -{ - SHFILEOPSTRUCTW op; - PyObject *filepath; - Py_ssize_t len; - WCHAR filechars[MAX_PATH+1]; - int r; - - if (!PyArg_ParseTuple(args, "O", &filepath)) { - return NULL; - } - - if (!PyUnicode_Check(filepath)) { - PyErr_SetString(PyExc_TypeError, "Unicode filename required"); - return NULL; - } - - len = PyUnicode_GET_SIZE(filepath); - memcpy(filechars, PyUnicode_AsUnicode(filepath), sizeof(WCHAR)*len); - filechars[len] = '\0'; - filechars[len+1] = '\0'; - - op.hwnd = 0; - op.wFunc = FO_DELETE; - op.pFrom = (LPCWSTR)&filechars; - op.pTo = NULL; - op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; - r = SHFileOperationW(&op); - - if (r != 0) { - PyErr_Format(PyExc_OSError, "Couldn't perform operation. Error code: %d", r); - return NULL; - } - - return Py_None; -} - -static PyMethodDef TrashMethods[] = { - {"send", send2trash_win_send, METH_VARARGS, ""}, - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef TrashDef = { - PyModuleDef_HEAD_INIT, - "send2trash_win", - NULL, - -1, - TrashMethods, - NULL, - NULL, - NULL, - NULL -}; - -PyObject * -PyInit_send2trash_win(void) -{ - PyObject *m = PyModule_Create(&TrashDef); - if (m == NULL) { - return NULL; - } - return m; -} \ No newline at end of file diff --git a/send2trash/plat_win.py b/send2trash/plat_win.py index 5f1a4d6..d3607be 100644 --- a/send2trash/plat_win.py +++ b/send2trash/plat_win.py @@ -4,12 +4,52 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license +from ctypes import windll, Structure, byref, c_uint +from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL import os.path as op -import send2trash_win + +shell32 = windll.shell32 +SHFileOperationW = shell32.SHFileOperationW + +class SHFILEOPSTRUCTW(Structure): + _fields_ = [ + ("hwnd", HWND), + ("wFunc", UINT), + ("pFrom", LPCWSTR), + ("pTo", LPCWSTR), + ("fFlags", c_uint), + ("fAnyOperationsAborted", BOOL), + ("hNameMappings", c_uint), + ("lpszProgressTitle", LPCWSTR), + ] + +FO_MOVE = 1 +FO_COPY = 2 +FO_DELETE = 3 +FO_RENAME = 4 + +FOF_MULTIDESTFILES = 1 +FOF_SILENT = 4 +FOF_NOCONFIRMATION = 16 +FOF_ALLOWUNDO = 64 +FOF_NOERRORUI = 1024 def send2trash(path): if not isinstance(path, str): path = str(path, 'mbcs') if not op.isabs(path): path = op.abspath(path) - send2trash_win.send(path) + fileop = SHFILEOPSTRUCTW() + fileop.hwnd = 0 + fileop.wFunc = FO_DELETE + fileop.pFrom = LPCWSTR(path + '\0') + fileop.pTo = None + fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT + fileop.fAnyOperationsAborted = 0 + fileop.hNameMappings = 0 + fileop.lpszProgressTitle = None + result = SHFileOperationW(byref(fileop)) + if result: + msg = "Couldn't perform operation. Error code: %d" % result + raise OSError(msg) + diff --git a/setup.py b/setup.py index 0e4f406..524e909 100644 --- a/setup.py +++ b/setup.py @@ -2,16 +2,6 @@ import sys import os.path as op from setuptools import setup -from distutils.extension import Extension - -exts = [] - -if sys.platform == 'win32': - exts.append(Extension( - 'send2trash_win', - [op.join('modules', 'send2trash_win.c')], - extra_link_args = ['shell32.lib'], - )) CLASSIFIERS = [ 'Development Status :: 5 - Production/Stable', @@ -33,7 +23,6 @@ setup( author_email='hsoft@hardcoded.net', packages=['send2trash'], scripts=[], - ext_modules = exts, url='http://hg.hardcoded.net/send2trash/', license='BSD License', description='Send file to trash natively under Mac OS X, Windows and Linux.',