Eryk Sun <[email protected]> added the comment:
Long-path support in Windows 10 does not extend to the lpCurrentDirectory
parameter of CreateProcessW. If the path length exceeds the old limit of
MAX_PATH - 2 characters (not counting the required trailing backslash and
null), CreateProcessW fails with either ERROR_DIRECTORY (267) or
ERROR_INVALID_PARAMETER (87).
If we pass lpCurrentDirectory as a long path, it fails with ERROR_DIRECTORY
(i.e. the directory name is invalid). This is a bit confusing because it maps
to Python NotADirectoryError, which is the common usage for ERROR_DIRECTORY.
CreateProcessW, however, uses it in its broadest sense. It also fails with this
error if lpCurrentDirectory can't be validated as an existing directory via
GetFileAttributesW.
If we pass lpCurrentDirectory as NULL (i.e. inherit the current directory) and
our current directory is a long path, CreateProcessW fails with
ERROR_INVALID_PARAMETER. The source of this error isn't obvious unless we know
what to look for, since all of the passed parameters are in fact valid.
However, I'm not sure how to clarify the error without making assumptions. In
particular, a future release of Windows 10 may remove this limitation, in which
case we could end up obscuring an unrelated error.
> the workaround is to use the "\\?\" prefix
Without long-path support, the working directory is always limited to MAX_PATH
- 2 characters. The \\?\ prefix doesn't help. A few years ago, the
documentation for SetCurrentDirectory [1] was changed to include an invalid
claim that we can use the \\?\ prefix. We need to go back to 2016 [2] to get
the correct documentation.
Windows doesn't even fully support setting the current directory to a device
path (i.e. prefixed by \\.\ or \\?\). Operations on rooted paths will fail
badly because the system computes an invalid working drive in this case. We can
observe the problem by calling GetFullPathNameW:
>>> os.chdir(r'\\.\C:\Temp')
>>> print(os.path._getfullpathname(r'\Temp'))
\\Temp
The incorrect result might even be a valid path, coincidentally. For example:
>>> print(os.getcwd())
\\.\C:\Temp
>>> os.chdir(r'\localhost\C$')
>>> print(os.getcwd())
\\localhost\C$
[1]:
https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory
[2]:
https://web.archive.org/web/20160428232130/https://msdn.microsoft.com/en-us/library/windows/desktop/aa365530(v=vs.85).aspx
----------
nosy: +eryksun
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue36213>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com