0

I'm working on a script to change a value in a txt file and then start up an application afterwards. I just cannot figure out how to get an absolute path. So calling os.system(path) is constantly failing because of a space in the directory I'm opening.

I've tried:

  • PureWindowsPath('path')
  • p = Path(path).resolve()
  • path = os.path.abspath(os.path.dirname(path))

Here is the part of the code:

def runtime(self):
    """ The container to execute the Class functions. """
    print('This script changes the X axis resolution value for Rocket League.\nThe game will launch after a value is entered.\n')

    path = os.path.abspath(os.path.dirname(open('config.txt').readlines()[1][11:] + 'common\\rocketleague\\Binaries\\Win32\\'))
    print(path)

    inp = input('Enter 1 for 1 Monitor.\nEnter 2 for 2 Monitors.\nEnter C to cancel\n').lower()

    if inp == '1':
        self.replace(self.ConfigFilePath, self.Monitors2, self.Monitors1)
    elif inp == 'c':
        return None
    else:
        self.replace(self.ConfigFilePath, self.Monitors1, self.Monitors2)

    print('Starting Rocket League...')

    os.system('START /D ' + str(path) + ' "" /wait RocketLeague.exe')
    time.sleep(2)

Output of execute.runtime() :

This script changes the X axis resolution value for Rocket League.
The game will launch after a value is entered.

D:\STEAM GAMES\steamapps\common\rocketleague\Binaries\Win32
Enter 1 for 1 Monitor.
Enter 2 for 2 Monitors.
Enter C to cancel
1
Starting Rocket League...
The system cannot find the file GAMES\steamapps\common\rocketleague\Binaries\Win32.

Thanks for taking a look!

Feocco
  • 640
  • 1
  • 6
  • 12
  • `os.system()` is for running commands, not getting absolute paths. EDIT: Oh, the path is part of a command. Doh. :P – Cyphase Aug 14 '15 at 05:39
  • Also please try to fix your indentation. – Cyphase Aug 14 '15 at 05:39
  • Did you try wrapping the path (when using in os.system() ) in quotes. – Anand S Kumar Aug 14 '15 at 05:41
  • have you tried adding double quotes around the path you get before passing it on to anything else? – JL Peyret Aug 14 '15 at 05:41
  • 3
    Use `subprocess.call()` instead of `os.system()` and hand in the command and all it parameters as a list. This way they will be quoted properly. See https://docs.python.org/2/library/subprocess.html for examples. – Klaus D. Aug 14 '15 at 05:44
  • 1
    Duplicate of http://stackoverflow.com/questions/35817/how-to-escape-os-system-calls-in-python - not actually related to absolute paths. – codewarrior Aug 14 '15 at 05:48
  • Note that the `/D` option of cmd's `start` command and the `cwd` parameter of Python's `subprocess.Popen` are both for setting the working directory of the child process, but the executable is found relative to the current working directory and `PATH` of the *parent* process. – Eryk Sun Aug 14 '15 at 05:49
  • `os.path.abspath` is not the problem; the problem is your use of `os.system`. – augurar Aug 14 '15 at 05:58

1 Answers1

0

There were two problems:

  1. I needed to put additional quotation marks in my command.

OLD: START /D ' + str(path) + ' "" /wait RocketLeague.exe

NEW: START /D "' + str(path) + '" "" /wait RocketLeague.exe

  1. I should have used the subprocess module.

This is my modified function. It's opening the application as expected.

def runtime(self):
    """ The container to execute the Class functions. """
    print('This script changes the X axis resolution value for Rocket League.\nThe game will launch after a value is entered.\n')

    path = os.path.abspath(os.path.dirname(open('config.txt').readlines()[1][11:] + 'common\\rocketleague\\Binaries\\Win32\\'))

    inp = input('Enter 1 for 1 Monitor.\nEnter 2 for 2 Monitors.\nEnter C to cancel\n').lower()

    if inp == '1':
        self.replace(self.ConfigFilePath, self.Monitors2, self.Monitors1)
    elif inp == 'c':
        return None
    else:
        self.replace(self.ConfigFilePath, self.Monitors1, self.Monitors2)

    process = subprocess.Popen('RocketLeague.exe', executable=r'D:\STEAM GAMES\steamapps\common\rocketleague\Binaries\Win32\\RocketLeague.exe')
    time.sleep(2)
Feocco
  • 640
  • 1
  • 6
  • 12
  • You're not using the `cwd` parameter of `Popen`, nor do you use `creationflags=subprocess.CREATE_NEW_CONSOLE`, so apparently you don't need the shell's `start` command at all. By all means use subprocess, but if you wanted to use `system`, the following should work: `os.system('"%s"' % os.path.join(path, 'RocketLeague.exe'))`. – Eryk Sun Aug 14 '15 at 06:53
  • To be honest, I'm not sure what the cwd parameter or creationflags will do. I will need to look into it, I'm very new to Python and programming. This is my 2nd 'real' project. Popen is accomplishing what I need it to. It launches the game after I've changed the resolution. I don't need any additional information after that point. Unless I wanted to add a failure to start message probably? – Feocco Aug 14 '15 at 15:05
  • `cwd` (current working directory) corresponds to the `/D` option of the `start` command. Also, if RocketLeague.exe were a console application the default for `start` is to create a new console window, which corresponds to the `CREATE_NEW_CONSOLE` process creation flag. My point is that the `Popen` command that you're happy with would more closely correspond to using `os.system` without `start`. Also, how you're using `start` in the "new" command wouldn't work anyway. – Eryk Sun Aug 14 '15 at 15:15
  • Awesome, thank you for explaining what those parameters do. I used the start command because I couldn't get another method working. I wasn't aware it's for creating a new console window. – Feocco Aug 14 '15 at 21:31
  • The `start` command customizes how the cmd shell executes a command or program. It can set whether a new console window gets created, the title (an old bug actually requires the title whenever quoted strings are used), and the minimized/maximized state. You can also set the working directory, environment (crudely), process priority, CPU affinity, and whether the shell waits for the process. Using the `/D` option has no effect on finding a program such as RocketLeague.exe. cmd uses its current working directory (unless the environment variable `NoDefaultCurrentDirectoryInExePath` is defined). – Eryk Sun Aug 14 '15 at 21:58