Asset - Extension Execute Shell (for Windows, macOS, and Ubuntu)

Discussion in 'Marketplace' started by Samuel Venable, Sep 13, 2016.

  1. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    [​IMG]

    [​IMG]

    [​IMG]

    This extension is for Windows, macOS and Ubuntu.

    Execute third-party applications from your GameMaker Studio games.

    Open or run any file type, whether EXE or not. Supports "wait" param.

    The DLL's full source code included.

    Very big thanks to Josh Ventura, for writing the widen() and shorten() scripts, enabling UTF-8 support on Windows.

    Download Free for GameMaker Studio 1.4 and 2
     
    Last edited: Oct 5, 2018
    EvanSki, Stoozey, Tthecreator and 4 others like this.
  2. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    This extension has had over 600 downloads, so I assume a good number of users here have it. Is anyone ok with showing me your project and how it uses my extension? I'm just a little curious as to what it is being used for.
     
  3. RizbIT

    RizbIT Member

    Joined:
    Jun 24, 2016
    Posts:
    436
    I had a similar one that kept crashing at game start. Is this one stable and work every time game starts?
     
  4. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Hi @RizbIT

    If you set the wait parameter to 1 on Windows and try to click on or mess with the main game window while waiting for the process to close, it will crash. This is a bug with GM:S itself and how it handles non-async dll calls on Windows. I reported it on the helpdesk and they said they're gonna fix it.

    So if you want the program to run asynchronously or you want to target Ubuntu you should be fine. This is a Windows-only issue. Set the second argument to 0 on Windows and you should be all set. :)

    For example:
    Code:
    ExecuteShell("notepad.exe",0);
     
    Last edited: Oct 23, 2016
  5. RizbIT

    RizbIT Member

    Joined:
    Jun 24, 2016
    Posts:
    436
    no i mean right at the start when you define the external call in the dll... on the other guys dll sometimes on game start it crashed at that point
     
  6. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    As long as the wait parameter is 0, there is no crash. It's been thoroughly tested. No crash at game start. No crash after game start.
     
  7. renex

    renex Member

    Joined:
    Jun 23, 2016
    Posts:
    506
    Samuel Venable likes this.
  8. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Great news everyone!

    Version 9.1.0 Released!

    • Finally fixed that nasty bug on Windows with setting the wait argument to true.

    • Added an optional third argument to allow opening files hidden on Windows.
     
  9. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Thanks to @appleWolf, this extension is now 64-bit Mac compatible! Well, hopefully. I still need someone to test it. The code is portable for Unix-based operating systems. I already know it works on Linux, which is Unix-based.

    Mac is also based on Unix, and it built without any errors, so I can't imagine it not working, unless someone tries it on an unsupported architecture. If you would like to be a tester, shoot me a PM! If it works as intended, I'll announce Mac is officially supported at the top of the asset's description. :D

    (testers will be credited)
     
  10. ElChingles

    ElChingles Member

    Joined:
    Oct 13, 2017
    Posts:
    5
    Last edited: May 26, 2018
    Samuel Venable likes this.
  11. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Version 9.3.0 Released!
    • Added official support for macOS.
     
  12. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    Hello!

    I am new here, but definitely not new to Gamemaker. I hope this is an okay place to ask this question. It is directly related to your extension (which is a pretty cool piece of work, by the way).

    So I programmed an updater/launcher in Gamemaker for Windows that downloads the executable file for my game and saves it to the launcher's dedicated app data folder. I then execute the program with your extension. The problem comes when there are multiple users on the system. The process all works flawlessly on the primary user account, but then when the secondary user uses the launcher, it downloads just fine, but will not execute the program.

    Here is the code that defines the folder's location:
    Code:
    globalvar place;
    place = environment_get_variable("LOCALAPPDATA") + "\Updater";
    "Updater" being the name of the launcher I have created. I've tried using "game_save_id", "working_directory", and "program_directory". The latter two do not work and the first yields the same result.

    Here is the code that downloads the file. This code works perfectly no matter the user account. I'm just including it to give you an idea of what's going on here:
    Code:
    size = ds_map_find_value(async_load,"contentLength");
    progress = ds_map_find_value(async_load,"sizeDownloaded");
    if (perc < 100)
    perc = round((progress/size)*100)
    if (ds_map_find_value(async_load, "id") == async_ini)
    {
          var status = ds_map_find_value(async_load,"status");
          if (status == 0 && statussss < 2)
          {
                statussss = 3;
                ini_open("localversion.ini");
                ini_write_real('version','number',ver);
                ini_close();
                statussss = 4;
                instance_create(x,y,o_Launch);
          }
    }
    Finally, here is the code that launches the game (the game executable being called "GunCave.exe"):
    Code:
    timer++;
    if (timer >= 30*60)
    {
        if (file_exists(place+"\GunCave.exe"))
        {
            o_Updater.neednew = 6;
            if (timer >= 33*60)
            {
                ExecuteShell(place+"\GunCave.exe", true);
                game_end();
            }
        }
        else
        {
            o_Updater.neednew = 7;
            if (timer >= 33*60)
            {
                game_end();
            }
        }
    }
    This is where the problem lies. This code works on the primary user account, but not on the secondary account. On the primary account, it successfully launches my game and then closes the launcher once the game is closed. On the secondary account, the game fails to launch and the launcher closes.

    I know I've read places that have discouraged making a launcher in Gamemaker, but I was able to create and get it to work, up until this issue. I hope someone can help me.

    Thanks in advance,
    ~Gravityhamster
     
    Last edited: Dec 6, 2018
  13. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    @Gravityhamster48 Hey!

    What's the difference between the two accounts? Is one of them by any chance not administrative? Does it require administrative privileges to run the exe?
     
  14. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    Thank you so much for replying!

    The executable does not require administrative privileges to run. Even so, though, I've tried making the secondary user both regular and administrator and the result is the same: The executable doesn't launch and the launcher program closes.
     
  15. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Try removing the file_exists call. I'm interested in hearing if it runs the file after commenting that out. I might have a solution if that ends up being the problem.

    I'd also check if the path and file exists manually, outside of code, i.e. in explorer, and also what value the environment variable returns on both users by contrast.
     
    Last edited: Dec 6, 2018
  16. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    It still does not work if I remove the "file_exists" call. I sent you in my original post the code for when it launches the game offline. If the the launcher detects that it cannot connect to my server to check for a new update, it will run the code I sent you. Otherwise, it checks for an update and runs this code instead, which has no "file_exists" present in it:
    Code:
    i++;
    if (i == 5)
    {
        ExecuteShell(place+"\GunCave.exe", true);
        game_end();
    }
    This code still does not launch the game correctly under the secondary account. (Obviously, it does run correctly under the primary account.)

    The executable file is present in the desired appdata folder and I can even manually execute the file from there and it runs fine. Also, when I run my launcher I draw the appdata directory (stored in variable "place") onto the screen. The directory is correct on both accounts, changing the username to match the current user account and matches the directory manually found in Windows Explorer.

    Hopefully that all makes sense. If you need clarification, please ask.
     
  17. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    I'm not sure even if I had your source code to debug with how much help that would be, it's really odd that it works on one account, but not the other. I hate to say it, but I'm stumped. Unless I can reproduce this issue myself, I don't see how I can figure out what's going wrong. :(
     
  18. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    Oh well. Thanks for trying!... Maybe I'll just have to go at it with a different approach. Maybe even make a launcher in a separate language. I dunno.

    I will say that you can create the same basic scenario by following these steps: Make a new user on your computer. You can easily do this in the settings and don't even have to make a new Microsoft account to do it (and it can easily be deleted later). Create a new project in Gamemaker. Have the project write a text file (I prefer a .ini file) so that it creates the appdata directory for your project, then manually place any standalone executable in the appdata directory for your project (These steps must be done under BOTH user accounts). Make an "ExecuteShell" command to run that program you put in the project's directory. Now export the project to an executable and run it. It should run the executable that you placed in the appdata folder for your program under your primary user account, but it should not successfully run under the secondary account.

    If it's too much of a pain to try to figure out, don't worry about it, but there's some basic steps if you wish to try to reproduce the issue.
     
    Samuel Venable likes this.
  19. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    I'll give that a shot tomorrow. It's getting late where I live. I'll get back to you with the results of my testing.

    Edit:

    Trying it now as we speak...

    Edit2:

    It works for me on both accounts. Am I doing something wrong?

    I run this on account 1:

    Code:
    if (os_type == os_windows)
    {
        ini_open("test.ini");
        ini_write_real("hello", "world", 1);
        ini_close();
       
        if (file_exists(game_save_id + 'notepad.exe'))
            ExecuteShell('"' + game_save_id + 'notepad.exe"', true);
    }
    
    game_end();
    It created the ini file but the exe needs to be copied there in order to run so I do that.

    Then I hit run again.

    Export project.

    Do all the same as above but on account 2.

    It all worked for me. notepad.exe ran on both accounts after I copied it to the correct folder on both accounts.
     
    Last edited: Dec 6, 2018
    Gravityhamster48 likes this.
  20. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    Yes! Thanks to you, it's fixed!!

    What I found out was that my syntax was incorrect. Here was the old code for the file path:
    Code:
    globalvar place;
    place = environment_get_variable("LOCALAPPDATA") + "\Updater";
    Execute:
    Code:
    i++;
    if (i == 5)
    {
        ExecuteShell(place+"\GunCave.exe", true);
        game_end();
    }
    And here is the new, working code for the file path execution:
    Code:
    i++
    if (i == 5)
    {
        ExecuteShell('"' + string(game_save_id) + 'GunCave.exe"', true);
        game_end();
    }
    I don't know if using "LOCALAPPDATA" rather than "game_save_id" would work, but it doesn't matter. I'd rather use "game_save_id" anyway. Here's the things I could note that you did differently compared to me:
    • First of all, you excluded the "\" before the executable.
    • Second, when I tried "game_save_id" I neglected to convert to a string.
    • Third, was the use of double and single quotes. Notice the difference between this:
      Code:
      place+"\GunCave.exe"
      and this:
      Code:
      '"' + string(game_save_id) + 'GunCave.exe"'
    • I also just removed the variable "place" for when I execute as a whole just to make it easier to implement the correct quotes and reduce confusion.
    Thank you so much for your help! I'm so glad that it was a problem with my code and not with the extension!

    You've been great to work with!
    ~Gravityhamster
     
    Samuel Venable likes this.
  21. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    I'm glad you've figured it out, and that I could help! Using the quotes within quotes is generally a good practice for command line stuff, since there are sometimes paths with spaces. Some path functions and variables do not include the final slash, but on Windows at least, I know working_directory and game_save_id have it. It may be different for getting the environment variables, as well as program_directory. I can't remember whether temp_directory has the last slash. In any case, I agree the inconsistency is a bit confusing and I have reported this to the bug tracker for GMS 1.4 and 2. However, they didn't fix it before the end of 1.4's lifetime, so your practice of using the extra slash is probably better, also because it is backwards compatible with pre-Studio GM versions.

    Edit:

    Also, as far as I know, you don't need to wrap game_save_id in a string() function. I did that by accident originally, but updated my post to remove that.
     
    Last edited: Dec 6, 2018
    Gravityhamster48 likes this.
  22. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    I have unfortunate news concerning the future of this project. It relies on Microsoft Script Control on Windows, i.e. "msscript.ocx" in your SysWOW64 folder, which is a legacy component built for 32-bit only by Microsoft. Normally I would just use CreateProcess or ShellExecute Windows API functions to achieve this, but for the wait parameter, a call to waiting for completion is necessary, and that crashes GameMaker due to a long-standing bug with GM's Runner.

    So anyway, I am relying on something that essentially does the same thing but with interpreted VBScript. This can be done with one of two mechanisms - Microsoft Script Control, which is 32-bit only. Or I could use the IActiveScript interface, which would also support the upcoming 64-bit Windows GM Runner, but ironically enough that crashes the Runner, just like CreateProcess and ShellExecute does, but only when the wait argument is true.

    As a final attempt to bypass all of this, i think I have good news as well. I just discovered while writing this post just now, that I can create an invisible modal dialog both the developer and the end user won't see, and allow that to create the waiting parameter to have the desired effect. Haven't tested it yet. Wish me luck! Will add my results in an edit.
     
  23. Gravityhamster48

    Gravityhamster48 Member

    Joined:
    Dec 6, 2018
    Posts:
    27
    That does sound unfortunate. I hope you can find a solution! However, if I do not receive a crash in my project as it stands now, do I need to worry about the bug?
     
  24. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    No, you don't. It only applied to certain methods that attempt to do the same thing. The current method doesn't do that.
     
    Gravityhamster48 likes this.
  25. BifTek

    BifTek Member

    Joined:
    Apr 18, 2019
    Posts:
    13
    Edit: Nevermind. This extension is great.
     
    Samuel Venable likes this.
  26. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Hey fam, so i fixed the Linux version which a user reported to me that it got stale and stopped working. Without changing the code, I simply rebuilt it with the latest G++ compiler. They said it works again now. Please let authors/publishers know if you ever run into similar issues down the line using extensions, as all of them on the marketplace that are not pure GML will need to be rebuilt over time to maintain compatibility with the latest systems.

    This update only fixes the GMS 2.x version. If you need the update for GMS 1.4 please contact and I'll send you the new files. I can't update the 1.4 version on the MP anymore because YoYo's uploader for that version is still broken.
     
  27. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    I downloaded this earlier, and was testing it out. It ran fine with the example where you bring up notepad and the calculator, but I wanted to load up an exe of a gamemaker project. I could see it being started, but it would shut down after appearing.

    The aim is to see if I can get two versions of the project running in sync, and use it for multi-threading somehow. This is what I did (bare in mind I'm not that savvy...)

    ExecuteShell('"C:\Windows\System32\calc.exe"', true); // your original code

    ExecuteShell('C:\Users\jb209\Downloads\gamemaker stuff\market place stuff\test_project.exe', true); // my alteration - which I assumed was all that this was doing...giving the directory location?

    Can you please let me know what I'm doing wrong? I just want to know why it doesn't stay open, and yet the calculator does when called in the same way.
     
  28. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Because there are spaces in that path, you will need to do:

    ExecuteShell('"C:\Users\jb209\Downloads\gamemaker stuff\market place stuff\test_project.exe"', true);
     
  29. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    Thanks for the help :) That fixed it.

    Does any part of this process give any control / communication between the two applications?

    EDIT:
    I've looked into networking, and have set up a project, so I imagine that covers it?
     
    Last edited: May 17, 2019
  30. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    If you made the executable yourself that you are trying to run, you can communicate between the two by reading and writing to external files, is that what you meant?
     
    Lonewolff likes this.
  31. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    I was initially thinking of reading and writing to files, though decided it's probably not the best way. The YOYO demo of the LAN platformer showed how to use networking on the same machine, and that seems simpler.

    Just wondered if there was anything inherent to execute shell that made doing the networking redundant (I still want to use it to open up the second exe though) , but I have the solution if it doesn't.
     
  32. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    Not that I know of, but I suppose it may be possible with shell scripts or something. I honestly don't know...
     
  33. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    Thanks anyway :)
     
    Samuel Venable likes this.
  34. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,135
    You could communicate between applications via window handles, processes, etc.. but you'd have to have applications that are aware of each other. Not too hard to achieve, but is out of scope of this type of extension. Not really the sort of thing that a shell execute is designed to do.
     
    the_dude_abides likes this.
  35. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    Thanks for the info. That sounds a bit beyond my capabilities (for now), but I have an alternative which should suffice.
     
  36. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    @matharoo informed me he is in the process of making a tutorial that does exactly what @the_dude_abides is looking for, and he said he is using my Execute Shell extension to do it. I love it when I make something that has more practical uses than I originally anticipated. I'm sure you being a much more experienced developer than I am have run into this kind of thing a lot more than I have. Regardless, one day i will be as good as you, just wait and see you stinker. :p
     
  37. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    Thanks Samuel for tagging me into that - I will be interested in that tutorial when matharoo gets around to it. I guess for me it's just a question of which form of "communication" is the least costly and / or effective to do - local networking and sending limited data in a form that fits a buffer, or whatever matharoo' process entails (which will hopefully be more direct in communicating / manipulating data).

    But that's getting a bit off topic from your original thread, so I'll leave it there. Cheers!
     
    Samuel Venable likes this.
  38. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,135
    You have been for a long time. You just don't realise it. :D

    [media][/media]
     
    Samuel Venable likes this.
  39. Joe Ellis

    Joe Ellis Member

    Joined:
    Aug 30, 2016
    Posts:
    890
    Legendary
     
    Samuel Venable and Lonewolff like this.
  40. matharoo

    matharoo Udemy Instructor

    Joined:
    Jul 9, 2016
    Posts:
    892
    Here's a script that opens two windows, if that's what you're looking for:
    Code:
    if (parameter_count() == 3) {
        ExecuteShell(parameter_string(0) + " " +
            parameter_string(1) + " " +
            parameter_string(2) + " " +
            parameter_string(3) + " -secondary" + " -tertiary", false, false)
        // <primary instance>
        window_set_caption("P1")
     
        window_set_position(200, 260);
    }
    
    if (parameter_count() > 3) {
        // <secondary instance>
        window_set_caption("P2")
     
        window_set_position(900, 260);
    }
    
    The tutorial Samuel's talking about is a networking tutorial, and that's why I needed two windows.
     
  41. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    @matharoo Thanks for the info. I will check out that tutorial, as I am looking into networking. I don't want to hijack the original thread, but while you have responded - my original question was if there was a direct way to control an exe opened through Execute Shell, rather than using local networking to communicate limited information.

    I'm not sure the parameter functions really cover exactly what I want to do, or that I have the capability to handle things directly. As an example: I have two exe of my game running, one is a slave, one is a master. If I make an mp grid in one, is it possible to manipulate it in the other? The networking attempt would simply be sending the data to be entered into the grid, whereas direct manipulation (if even possible) entails...dunno, beyond my pay grade :) One version being pointed to the memory that is storing the variables and info from the other version, and....*my brain explodes as it tries to consider what that involves*

    Will your tutorial cover anything like that?
     
    matharoo likes this.
  42. matharoo

    matharoo Udemy Instructor

    Joined:
    Jul 9, 2016
    Posts:
    892
    Nope, the tutorial only covers TCP networking.

    I think @YellowAfterlife could know how you could control the memory in the other instance, if it is possible.
     
    the_dude_abides likes this.
  43. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
    Not without tricks that are unjustifiably complex - with some luck (see this), you could expose functions to a C++ DLL, and then write another DLL to allow the first process to run path_get_point_x/y functions on mp_grid paths in the second process, and communicate path indexes between them, but at this point a sizable chunk of your code would move to C++, and all for what
     
    the_dude_abides likes this.
  44. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    Ouch! That is quite beyond my capabilities.....Soooo, uh, I'll stick to a more manageable solution. Thanks for replying :)

    EDIT:
    That link is interesting, so thanks for that too. I will see if I can understand it. This is still linked to using Execute Shell, but it feels like me asking you further questions would be hijacking this topic. If I wanted to ask you about the meaning of 'function_get_address" would a PM be okay, or is there a thread about it?
     
    Last edited: May 20, 2019
  45. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
    I suppose a separate topic would work best - that way it'll also be useful for anyone else with same questions
     
  46. the_dude_abides

    the_dude_abides Member

    Joined:
    Jun 23, 2016
    Posts:
    588
    I will do that then, but at the moment I have a problem that needs ironing out before looking at the next stages. Once it gets that far I will do a thread, and tag you to it if that is okay?
     
    YellowAfterlife likes this.
  47. ocnuybear

    ocnuybear Member

    Joined:
    Jun 19, 2019
    Posts:
    20
    Cannot start Python - please assist?
    Code:
    ExecuteShell("C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe",true);
    Nothings happens, but I can start Python using that from command prompt
     
    Samuel Venable likes this.
  48. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,216
    You have spaces in that path. You need to use quotes within quotes around the path. For passing arguments, if those contain spaces as well you'll need quotes around that too within the initial quotes. This also applies to when using the command line, if you dont put quotes around the path with spaces, it won't work.

    GMS 1.4 example:
    Code:
    ExecuteShell('"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe"',true);
    GMS 2.x example:
    Code:
    ExecuteShell(@'"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe"',true);
    And if you need arguments with potential whitespace hazards...

    GMS 1.4 example:
    Code:
    ExecuteShell('"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe" "C:\Program Files (x86)\Python Scripts\example.py"',true);
    GMS 2.x example:
    Code:
    ExecuteShell(@'"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe" "C:\Program Files (x86)\Python Scripts\example.py"',true);
    Always use quotes within quotes as a standard practice because there's no telling in some cases whether there will be spaces in the directory specified necessarily, i.e. if you use the working_directory constant, for example.
     
    Last edited: Jul 7, 2019
    ocnuybear likes this.
  49. ocnuybear

    ocnuybear Member

    Joined:
    Jun 19, 2019
    Posts:
    20
    Great thank you Samuel, still very new to GM2 and also learning how to escape the commas & spaces.
     
    Samuel Venable likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice