This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: windows installer quiet installation targetdir escapes "quote"-symbol
Type: behavior Stage:
Components: Installation, Windows Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: DMI-1407, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2021-09-01 04:39 by DMI-1407, last changed 2022-04-11 14:59 by admin.

Messages (2)
msg400809 - (view) Author: (DMI-1407) Date: 2021-09-01 04:39
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. :/
msg400811 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-09-01 05:21
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
History
Date User Action Args
2022-04-11 14:59:49adminsetgithub: 89236
2021-09-01 05:21:47eryksunsetnosy: + paul.moore, tim.golden, eryksun, zach.ware, steve.dower
messages: + msg400811
components: + Windows
2021-09-01 04:39:04DMI-1407create