skip to Main Content

I have a Thumbnail_Handler class which has this method, which is supposed to run a file with Adobe Photoshop:

def abrir_photoshop(self):
        target = self.path_copia
        norm_path = os.path.normpath(r"C:\Program FilesAdobeAdobe Photoshop 2021\Photoshop.exe")
        cmd = '"' + norm_path + '" "' + target + '"'
        print(cmd)
        proc = os.system(cmd)
        for filename in os.listdir(PATH_THUMBNAIL + self.nome_playlist):
            if re.match(self.id_video_original + '.*.png', filename):
                self.set_status(status_thumb.PNG_EXPORTADO)
                return filename

The command that is printed on the print(cmd) line is this: "C:Program FilesAdobeAdobe Photoshop 2021Photoshop.exe" "C:\Users\adassaDesktop\Thiago\Youtube Almir\PSDsNão Temas - 8PydQGvI0E4.psd"

If I simply copy this, and paste to Powershell, or to the common Windows shell, it works as intended, but when python runs the command, I get: 'C:Program' is not recognized as a command. I reckon this means that the command is going without the double quotes. Why does this happen, and how can I correct it?

3

Answers


  1. mslex.quote from mslex package looks like a solution to your case.

    shelx.quote exits for same task on unix-like systems.

    Login or Signup to reply.
  2. When i tried a path similar to yours it only tried to run ‘C:Program’ if the path did not existed, otherwise it worked fine, but since you said it worked when you manually copied the path maybe it’s something else.

    I found two ways to force the proper path:

    Solution 1: Quote only part of the path

    norm_path = os.path.normpath(r'C:"Program FilesAdobeAdobe Photoshop 2021Photoshop.exe"')
    

    Solution 2: Escape the space with a caret

    norm_path = os.path.normpath(r'C:Program^ FilesAdobeAdobe^ Photoshop 2021Photoshop.exe')
    
    Login or Signup to reply.
  3. os.system calls [MS.Docs]: system, _wsystem, which in turn calls the command interpreter (cmd).

    When system invokes cmd (I didn’t see any official documentation to support this, so I’m posting a screenshot to support my statement), it passes the /c argument:

    img0

    According to [MS.Docs]: cmd or cmd /? (emphasis is mine):

    • If you specify /c or /k, cmd processes, the remainder of string, and the quotation marks are preserved only if all of the following conditions are met:
      • You don’t also use /s.
      • You use exactly one set of quotation marks.
      • You don’t use any special characters within the quotation marks (for example: & < > ( ) @ ^ | ).
      • You use one or more white-space characters within the quotation marks.
      • The string within quotation marks is the name of an executable file.

    If the previous conditions aren’t met, string is processed by examining the first character to verify whether it is an opening quotation mark. If the first character is an opening quotation mark, it is stripped along with the closing quotation mark. Any text following the closing quotation marks is preserved.

    So, when passing a quoted executable, followed by a quoted argument, cmd alters the command yielding the weird results you’re seeing.

    I don’t know if this behavior could be avoided, (maybe symlinks with no spaces in their path could be created and passed to os.system), but that would be just a lame workaround (gainarie). The common sense approach would be to use [Python.Docs]: subprocess – Subprocess management.

    code00.py:

    #!/usr/bin/env python
    
    import sys
    import os
    import subprocess
    
    
    def quote(s):
        return '"' + s + '"'
    
    
    def os_system(*args):
        cmd = " ".join(args)
        print("nRun command: [{:s}]".format(cmd))
        return os.system(cmd)
    
    
    def main(*argv):
        exe = os.path.normpath(r"c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe")
        quoted_exe = quote(exe)
        files = [
            "e:WorkDevStackOverflowq066659951dummy_no_spaces.pdf",
            "e:WorkDevStackOverflowq066659951dummy with spaces.pdf",
        ]
    
        if len(argv):
            print("Using subprocess")
            for file in files:
                subprocess.call([exe, file])
            return 0
    
        os_system(quoted_exe)
        os_system(exe)
        for file in files:
            os_system(quoted_exe, file)
            os_system(quoted_exe, quote(file))
    
    
    if __name__ == "__main__":
        print("Python {0:s} {1:d}bit on {2:s}n".format(" ".join(elem.strip() for elem in sys.version.split("n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        rc = main(*sys.argv[1:])
        print("nDone.")
        sys.exit(rc)
    

    Output:

    [cfati@CFATI-5510-0:e:WorkDevStackOverflowq066659951]> "e:WorkDevVEnvspy_pc064_03.08.07_test0Scriptspython.exe" code00.py
    Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 64bit on win32
    
    
    Run command: ["c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe"]
    
    Run command: [c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe]
    'c:Program' is not recognized as an internal or external command,
    operable program or batch file.
    
    Run command: ["c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe" e:WorkDevStackOverflowq066659951dummy_no_spaces.pdf]
    
    Run command: ["c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe" "e:WorkDevStackOverflowq066659951dummy_no_spaces.pdf"]
    'c:Program' is not recognized as an internal or external command,
    operable program or batch file.
    
    Run command: ["c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe" e:WorkDevStackOverflowq066659951dummy with spaces.pdf]
    
    Run command: ["c:Program Files (x86)AdobeAcrobat Reader DCReaderAcroRd32.exe" "e:WorkDevStackOverflowq066659951dummy with spaces.pdf"]
    'c:Program' is not recognized as an internal or external command,
    operable program or batch file.
    
    Done.
    
    [cfati@CFATI-5510-0:e:WorkDevStackOverflowq066659951]> :: !!! Now running via subprocess !!!
    [cfati@CFATI-5510-0:e:WorkDevStackOverflowq066659951]> "e:WorkDevVEnvspy_pc064_03.08.07_test0Scriptspython.exe" code00.py 1
    Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 64bit on win32
    
    Using subprocess
    
    Done.
    

    As seen:

    • In the 1st run (os.system), the variants that worked were (quoted executable):

      • Without arguments
      • With unquoted arguments (but for the file with spaces in its path, Acrobat Reader wasn’t able to open it, so it also failed – but at a later stage)
    • In the 2nd one (subprocess), everything worked smoothly (and Acrobat Reader had no problem opening the files – you’ll have to trust me on this one 🙂 ), no additional quoting required at all

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search