ThirdParty/Send2Trash/send2trash/plat_win.py

changeset 6228
9c3fbf39ec9b
parent 5994
cf0b37d2a28d
equal deleted inserted replaced
6227:fc0869cd16dc 6228:9c3fbf39ec9b
5 # http://www.hardcoded.net/licenses/bsd_license 5 # http://www.hardcoded.net/licenses/bsd_license
6 6
7 from __future__ import unicode_literals 7 from __future__ import unicode_literals
8 8
9 from ctypes import (windll, Structure, byref, c_uint, 9 from ctypes import (windll, Structure, byref, c_uint,
10 create_unicode_buffer, sizeof, addressof) 10 create_unicode_buffer, addressof)
11 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL 11 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL
12 import os.path as op 12 import os.path as op
13 13
14 from .compat import text_type 14 from .compat import text_type
15 15
16 kernel32 = windll.kernel32
17 GetShortPathNameW = kernel32.GetShortPathNameW
18
16 shell32 = windll.shell32 19 shell32 = windll.shell32
17 SHFileOperationW = shell32.SHFileOperationW 20 SHFileOperationW = shell32.SHFileOperationW
21
18 22
19 class SHFILEOPSTRUCTW(Structure): 23 class SHFILEOPSTRUCTW(Structure):
20 _fields_ = [ 24 _fields_ = [
21 ("hwnd", HWND), 25 ("hwnd", HWND),
22 ("wFunc", UINT), 26 ("wFunc", UINT),
26 ("fAnyOperationsAborted", BOOL), 30 ("fAnyOperationsAborted", BOOL),
27 ("hNameMappings", c_uint), 31 ("hNameMappings", c_uint),
28 ("lpszProgressTitle", LPCWSTR), 32 ("lpszProgressTitle", LPCWSTR),
29 ] 33 ]
30 34
35
31 FO_MOVE = 1 36 FO_MOVE = 1
32 FO_COPY = 2 37 FO_COPY = 2
33 FO_DELETE = 3 38 FO_DELETE = 3
34 FO_RENAME = 4 39 FO_RENAME = 4
35 40
37 FOF_SILENT = 4 42 FOF_SILENT = 4
38 FOF_NOCONFIRMATION = 16 43 FOF_NOCONFIRMATION = 16
39 FOF_ALLOWUNDO = 64 44 FOF_ALLOWUNDO = 64
40 FOF_NOERRORUI = 1024 45 FOF_NOERRORUI = 1024
41 46
47
48 def get_short_path_name(long_name):
49 if not long_name.startswith('\\\\?\\'):
50 long_name = '\\\\?\\' + long_name
51 buf_size = GetShortPathNameW(long_name, None, 0)
52 output = create_unicode_buffer(buf_size)
53 GetShortPathNameW(long_name, output, buf_size)
54 return output.value[4:] # Remove '\\?\' for SHFileOperationW
55
56
42 def send2trash(path): 57 def send2trash(path):
43 if not isinstance(path, text_type): 58 if not isinstance(path, text_type):
44 path = text_type(path, 'mbcs') 59 path = text_type(path, 'mbcs')
45 if not op.isabs(path): 60 if not op.isabs(path):
46 path = op.abspath(path) 61 path = op.abspath(path)
62 path = get_short_path_name(path)
47 fileop = SHFILEOPSTRUCTW() 63 fileop = SHFILEOPSTRUCTW()
48 fileop.hwnd = 0 64 fileop.hwnd = 0
49 fileop.wFunc = FO_DELETE 65 fileop.wFunc = FO_DELETE
50 # FIX: https://github.com/hsoft/send2trash/issues/17 66 # FIX: https://github.com/hsoft/send2trash/issues/17
51 # Starting in python 3.6.3 it is no longer possible to use: 67 # Starting in python 3.6.3 it is no longer possible to use:
52 # LPCWSTR(path + '\0') directly as embedded null characters are no longer 68 # LPCWSTR(path + '\0') directly as embedded null characters are no longer
53 # allowed in strings 69 # allowed in strings
54 # Workaround 70 # Workaround
55 # - create buffer of c_wchar[] (LPCWSTR is based on this type) 71 # - create buffer of c_wchar[] (LPCWSTR is based on this type)
56 # - buffer is two c_wchar characters longer (double null terminator) 72 # - buffer is two c_wchar characters longer (double null terminator)
57 # - cast the address of the buffer to a LPCWSTR 73 # - cast the address of the buffer to a LPCWSTR
58 # NOTE: based on how python allocates memory for these types they should 74 # NOTE: based on how python allocates memory for these types they should
59 # always be zero, if this is ever not true we can go back to explicitly 75 # always be zero, if this is ever not true we can go back to explicitly

eric ide

mercurial