diff -r 4b2b9be7de14 -r cf0b37d2a28d ThirdParty/Send2Trash/send2trash/plat_win.py --- a/ThirdParty/Send2Trash/send2trash/plat_win.py Sat Nov 25 13:49:54 2017 +0100 +++ b/ThirdParty/Send2Trash/send2trash/plat_win.py Thu Nov 30 17:00:18 2017 +0100 @@ -1,12 +1,13 @@ -# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) +# 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 +# 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 +from ctypes import (windll, Structure, byref, c_uint, + create_unicode_buffer, sizeof, addressof) from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL import os.path as op @@ -46,7 +47,19 @@ fileop = SHFILEOPSTRUCTW() fileop.hwnd = 0 fileop.wFunc = FO_DELETE - fileop.pFrom = LPCWSTR(path + '\0') + # 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 @@ -54,6 +67,4 @@ fileop.lpszProgressTitle = None result = SHFileOperationW(byref(fileop)) if result: - msg = "Couldn't perform operation. Error code: %d" % result - raise OSError(msg) - + raise WindowsError(None, None, path, result)