eric6/ThirdParty/Send2Trash/send2trash/plat_win.py

changeset 6942
2602857055c5
parent 6228
9c3fbf39ec9b
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # Copyright 2017 Virgil Dupras
2
3 # This software is licensed under the "BSD" License as described in the "LICENSE" file,
4 # which should be included with this package. The terms are also available at
5 # http://www.hardcoded.net/licenses/bsd_license
6
7 from __future__ import unicode_literals
8
9 from ctypes import (windll, Structure, byref, c_uint,
10 create_unicode_buffer, addressof)
11 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL
12 import os.path as op
13
14 from .compat import text_type
15
16 kernel32 = windll.kernel32
17 GetShortPathNameW = kernel32.GetShortPathNameW
18
19 shell32 = windll.shell32
20 SHFileOperationW = shell32.SHFileOperationW
21
22
23 class SHFILEOPSTRUCTW(Structure):
24 _fields_ = [
25 ("hwnd", HWND),
26 ("wFunc", UINT),
27 ("pFrom", LPCWSTR),
28 ("pTo", LPCWSTR),
29 ("fFlags", c_uint),
30 ("fAnyOperationsAborted", BOOL),
31 ("hNameMappings", c_uint),
32 ("lpszProgressTitle", LPCWSTR),
33 ]
34
35
36 FO_MOVE = 1
37 FO_COPY = 2
38 FO_DELETE = 3
39 FO_RENAME = 4
40
41 FOF_MULTIDESTFILES = 1
42 FOF_SILENT = 4
43 FOF_NOCONFIRMATION = 16
44 FOF_ALLOWUNDO = 64
45 FOF_NOERRORUI = 1024
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
57 def send2trash(path):
58 if not isinstance(path, text_type):
59 path = text_type(path, 'mbcs')
60 if not op.isabs(path):
61 path = op.abspath(path)
62 path = get_short_path_name(path)
63 fileop = SHFILEOPSTRUCTW()
64 fileop.hwnd = 0
65 fileop.wFunc = FO_DELETE
66 # FIX: https://github.com/hsoft/send2trash/issues/17
67 # Starting in python 3.6.3 it is no longer possible to use:
68 # LPCWSTR(path + '\0') directly as embedded null characters are no longer
69 # allowed in strings
70 # Workaround
71 # - create buffer of c_wchar[] (LPCWSTR is based on this type)
72 # - buffer is two c_wchar characters longer (double null terminator)
73 # - cast the address of the buffer to a LPCWSTR
74 # NOTE: based on how python allocates memory for these types they should
75 # always be zero, if this is ever not true we can go back to explicitly
76 # setting the last two characters to null using buffer[index] = '\0'.
77 buffer = create_unicode_buffer(path, len(path)+2)
78 fileop.pFrom = LPCWSTR(addressof(buffer))
79 fileop.pTo = None
80 fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT
81 fileop.fAnyOperationsAborted = 0
82 fileop.hNameMappings = 0
83 fileop.lpszProgressTitle = None
84 result = SHFileOperationW(byref(fileop))
85 if result:
86 raise WindowsError(None, None, path, result)

eric ide

mercurial