--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/ThirdParty/Send2Trash/send2trash/plat_win.py Sun Apr 14 15:09:21 2019 +0200 @@ -0,0 +1,86 @@ +# Copyright 2017 Virgil Dupras + +# 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 + +from __future__ import unicode_literals + +from ctypes import (windll, Structure, byref, c_uint, + create_unicode_buffer, addressof) +from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL +import os.path as op + +from .compat import text_type + +kernel32 = windll.kernel32 +GetShortPathNameW = kernel32.GetShortPathNameW + +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 get_short_path_name(long_name): + if not long_name.startswith('\\\\?\\'): + long_name = '\\\\?\\' + long_name + buf_size = GetShortPathNameW(long_name, None, 0) + output = create_unicode_buffer(buf_size) + GetShortPathNameW(long_name, output, buf_size) + return output.value[4:] # Remove '\\?\' for SHFileOperationW + + +def send2trash(path): + if not isinstance(path, text_type): + path = text_type(path, 'mbcs') + if not op.isabs(path): + path = op.abspath(path) + path = get_short_path_name(path) + fileop = SHFILEOPSTRUCTW() + fileop.hwnd = 0 + fileop.wFunc = FO_DELETE + # FIX: https://github.com/hsoft/send2trash/issues/17 + # Starting in python 3.6.3 it is no longer possible to use: + # LPCWSTR(path + '\0') directly as embedded null characters are no longer + # allowed in strings + # Workaround + # - create buffer of c_wchar[] (LPCWSTR is based on this type) + # - buffer is two c_wchar characters longer (double null terminator) + # - cast the address of the buffer to a LPCWSTR + # NOTE: based on how python allocates memory for these types they should + # always be zero, if this is ever not true we can go back to explicitly + # setting the last two characters to null using buffer[index] = '\0'. + buffer = create_unicode_buffer(path, len(path)+2) + fileop.pFrom = LPCWSTR(addressof(buffer)) + 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: + raise WindowsError(None, None, path, result)