Open 1ce60f14-740b-4dd9-acd9-6604a5da9bb4 opened 3 years ago
If the windows installer (Python 3.8.9 64bit exe) is run in quiet mode and the TargetDir option is used, then the last quote (") symbol gets escaped if the path ends with an backslash (\).
Example: /quiet TargetDir="D:\pyt hon\" AssociateFiles=0 Result: TargetDir=hon\" AssociateFiles=0 this raises the error that the path contains a invalid character... (the quote ofc)
Example: /quiet TargetDir="D:\pyt hon" AssociateFiles=0 Result: installs correctly
so in general "D:\pyt hon" indicates a file thats named "pyt hon" where "D:\pyt hon\" indicates a folder. whatever "D:\pyt hon\" should be valid and i dont understand why the first backslash does not escape the p and leads to "D:pyt hon" ...
its really annoying, pls do at least write a notice into the docs that the installer behaves like this. :/
A literal backlash has to be escaped by doubling it if it precedes a double quote, else it escapes the double quote character. This is how typical command-line argument parsing handles backslash in Windows [1]:
* 2n backslashes followed by a quotation mark produce n backslashes
followed by begin/end quote. This does not become part of the
parsed argument, but toggles the "in quotes" mode.
* (2n) + 1 backslashes followed by a quotation mark again produce n
backslashes followed by a quotation mark literal ("). This does
not toggle the "in quotes" mode.
* n backslashes not followed by a quotation mark simply produce n
backslashes.
For example:
import ctypes
shell32 = ctypes.WinDLL('shell32', use_last_error=True)
shell32.CommandLineToArgvW.restype = ctypes.POINTER(ctypes.c_wchar_p)
n = ctypes.c_int()
Escape the trailing backslash as a literal backslash:
>>> cmd = r'/quiet TargetDir="D:\pyt hon\\" AssociateFiles=0'
>>> args = shell32.CommandLineToArgvW(cmd, ctypes.byref(n))
>>> args[:n.value]
['/quiet', 'TargetDir=D:\\pyt hon\\', 'AssociateFiles=0']
Escape the double quote as a literal double quote:
>>> cmd = r'/quiet TargetDir="D:\pyt hon\" AssociateFiles=0'
>>> args = shell32.CommandLineToArgvW(cmd, ctypes.byref(n))
>>> args[:n.value]
['/quiet', 'TargetDir=D:\\pyt hon" AssociateFiles=0']
[1] https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = None closed_at = None created_at =
labels = ['3.8', 'type-bug', 'expert-installation', 'OS-windows']
title = 'windows installer quiet installation targetdir escapes "quote"-symbol'
updated_at =
user = 'https://bugs.python.org/DMI-1407'
```
bugs.python.org fields:
```python
activity =
actor = 'eryksun'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Installation', 'Windows']
creation =
creator = 'DMI-1407'
dependencies = []
files = []
hgrepos = []
issue_num = 45073
keywords = []
message_count = 2.0
messages = ['400809', '400811']
nosy_count = 6.0
nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'DMI-1407']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue45073'
versions = ['Python 3.8']
```