ExecFile with Arguments?
BlitzMax Forums/BlitzMax Programming/ExecFile with Arguments?
| ||
Ok, I did my research before asking this question. I've seen a bunch of solutions but NONE of them offer executing an external .exe with arguments from BlitzMax. I loaded up B3D and tried ExecFile with args and it works like a charm. Why, pray tell, do we not have this basic functionality in BlitzMax? |
| ||
Have you tried OpenUrl()? |
| ||
Yep, and it doesn't accept arguments. If you try to put some on there it opens up IE. I've been sitting here wracking my brain for a few hours. Even tried to get some external javascript going. CreateProcess doesn't accept arguments. OpenURL doesn't accept arguments, system_ accepts arguments but doesn't shut down the main app. I just need a command that will call an external .exe with arguments and then allow the calling app to close. Blitz3D can do it. I'm freakin' boggled atm. Brb going for a beer... EDIT: So you've got 3 commands in BlitzMax that are similar but don't do the 1 command in Blitz3D. I'm gonna solve this even if I have to tear my computer apart and short circuit the CPU with a chainsaw. |
| ||
That's weird. Hmmmm, if you are OK with the new executable terminating when your own program closes, try CreateProcess(). |
| ||
I need the calling program to close. system_ seems like it 'could' work but I guess i'd have to get into the source code to modify it. There should just be a flag on the system_ that allows the app to continue running so it can hit the End command. |
| ||
I think this is more of a bug of OpenUrl() - under the hood, this function calls ShellExecute() which is expecting the arguments to be passed as a separate parameter to the executable filepath. Anyone any good with C strings fancies coding a parser for bbOpenUrl() that looks for the ".exe" extension in the path, splits the string at this point, and passes the two parts of the string as the appropriate parameters for ShellExecute? Brucey, how you doing? :P |
| ||
I'm kneedeep in the system.bmx code and I'm gonna fix this...with BEER in hand!! |
| ||
Uh oh...I tried to rebuild the modules and system.bmx has an error...it's gonna be a long night and I'm running low on beer... |
| ||
Ok there we go...now it's compiling. I'll post the OpenURL fix when I get it finished...and it WILL accept args whether it wants to or not. |
| ||
Can you put the parameters into quotes? for example, when entering command-line arguements in windows that contain spaces you need to completely enclose the command in "'s |
| ||
Quotes might work with system_, they probably won't with TProcess and the like. Might be better to write a wrapper around things like NSTask and whatever Linux and Windows have (might be much more painful to do it under those two, though). I'd start looking into that, myself. |
| ||
I modded CreateProcess to leave the process running after the app was closed. It was fairly simple, I think I posted how I did it here. Search for a post by me with CreateProcess in the text. |
| ||
This is the thread: http://www.blitzmax.com/Community/posts.php?topic=69287#928765 |
| ||
system_ works just fine with arguments but you can't close the main app that you called it from. In theory, a MaxGUI app gathers info and then executes the server with arguments. I just can't nail down the latter part. |
| ||
You obviously didn't look hard enough! |
| ||
Chroma, all you need to do is use the standard API call. |
| ||
all you need to do is use the standard API call. I tried it, but it wouldn't even compile on my Mac... |
| ||
Brucey, You joking, right? Are you compiling this for Windows? I would like to help, but I have not used Win32 API calls since the late 90s. I'm just out of practice ;) Jason |
| ||
Lol, I actually had that command typed in almost just like that but I didn't have it quite right. I'll try that as soon as I get home. After researching more last night, I knew the ShellExecute() command was a win32 API call but I just couldn't nail it down. Can't wait to try it. But, I ask all you fine gentlemen. Is there a Cross-Platform solution to this? I need my dedicated server to be able to run on all 3 systems. Extern "win32" Function ShellExecuteA(hwnd,op$z,file$z,params$z,dir$z,showcmd) End Extern ShellExecuteA(0,"open","calc.exe","","",SW_SHOWNORMAL) |
| ||
Best to post a small bit of code to test the functionality on each platform and ask people to try it, I think you'll probably get away with using OpenURL for Linux and probably MacOS too. Ask some people with those platforms to test it for you. Then just make a wrapper function OpenURLx or something and inside put 'ifdef' or whatever the equivalent is in BlitzMax so the function gets compiled with the right command for the platform. Edit: I hope this isn't for your Threading Server? |
| ||
It's just for the front end of the server where you select the map, number of players, day/night cycle. Then you click Start Server and it's executes the server.exe with arguments. I guess I could write all the info to an .ini file and just have the server read it. That'd be much easier for sure and then I wouldn't have cross-platform issues. Basically, in the beginning at least, the dedicated server is basically an echo server (TCP) that let's a player connect and then sends the player the info on what map to load etc. Then the player gets into the game and starts throwing packets at the server, which are broadcast to every other player. The server app isn't very big and it get's about 8,000,000 fps. I'm not even setting graphics. I'm just building the bmax app with the GUI Build unchecked. So it kinda runs in a console looking window. Printing will print text to the console so I print when a player connects or disconnects. It should be plenty fast enough to handle everything. I want to try writing it in stackless python also. FlameDuck mentioned that's about the best language to write a server in. |
| ||
CreateProcess("myprogram.exe arguments") |
| ||
I'm at work so I can't test, but does that let the calling app terminate and let the called app still run? And is that cross-platform? ie. CreateProcess("server.exe IslandMap 24") End EDIT: Hmm, I'll probably have to go in and mod the bmx source like TaskMaster did. |
| ||
You joking, right? Perhaps, but it was highly likely that this : Is there a Cross-Platform solution to this? ...was to follow at some point. In which case, a Win32 API solution is going to be about 1/3rd useful. does that let the calling app terminate and let the called app still run? And is that cross-platform? Probably not, and yes. Although you will have to wrap arguments with spaces in quotes (~qarg with spaces~q). What TProcess wants is a Detach() method or something. Skid?? |
| ||
The changes I made to freeprocess.bmx are: Whoops, I posted the entire moded module, not good. I realized I should not be posting the source code to a BlitzMax mod to the public forum. I will list the changes I made. Around Line 41: After: Const HIDECONSOLE=1 Add: Const LIVE = 2 In the TProcess type Around Line 129: After: Field err:TPipeStream Add: Field bLive:Int = False In TProcess.TerminateAll() After: For p=EachIn ProcessList Add: If Not p.bLive p.Terminate 'MOD Three simple lines added. This will leave any process, you set the flags to include LIVE, running when your app exits. To terminate the process, you have to terminate it yourself or let it end on its own. |
| ||
let the calling app terminate and let the called app still run This method seems to work... Function Quit () OpenURL ("C:\Windows\notepad.exe") End Function OnEnd Quit Print "Hello" End |
| ||
But he needs to pass a parameter, and OpenURL does not do that. You can't do this: OpenURL("c:\windows\notepad.exe file.txt") |
| ||
Apparently CreateProcess() doesn't allow arguments either... Just tested in on lunch break. Even used Brucey's ~qarg arg~q way to do it. Stumped in Seattle. |
| ||
It works just fine for me. I have a line like this: Local proc:TProcess = CreateProcess("manage.exe " + Chr(34) + DestDir + Chr(34), LIVE) Ascii code 34 is a quotation mark. Using quotes because the dir may have spaces. |
| ||
Local proc:TProcess = CreateProcess("manage.exe " + Chr(34) + DestDir + Chr(34), LIVE) Why are you writing Chr(34) when you can just use ~q for a quote? E.g., "manage.exe ~q"+DestDir+"~q". |
| ||
Why are you writing Chr(34) Because Chr(34) is only 1 character, whereas ~q is 2 ? |
| ||
Because Chr(34) is only 1 character, whereas ~q is 2 ? My head just exploded. Thanks, Brucey - now I gotta find all those bits and pieces again. |
| ||
Hmm...that line doesn't work for me TaskMaster. I'm running it from the same folder tha the exe is in that i'm calling. I even tested it with throwing CurrentDir$() on the front with a "/" and it doesn't work. |
| ||
A "/" ? What platform is that? Same folder should work on Windows. Otherwise (for Linux/Mac), try adding "./" - on the assuming that dot (.) is not on the PATH. |
| ||
I didn't know about the ~q. That is why I used Chr(34). |
| ||
@ Brucey: I mean I put a "/" between the currentdir and MyServer.eve:CreateProcess(CurrentDir$()+"/MyServer.exe "+Chr$(34)+"blah1 blah2"+Chr$(34) The above isn't working either. I've not messed with and Process source code so I'm stumped. |
| ||
No, Chroma, Chr(34) is bad. Baaaaad. |
| ||
I mean I put a "/" between the currentdir and MyServer.eve: Well, on Windows you probably want to be using \ instead of / ? |
| ||
windows should support the forward slash as well |
| ||
Haha well I can't get either one to work. So I went with just spitting out an .ini file and then doing an OpenURL on the other app. Then the new app reads the .ini file and deletes it. That solves the cross-platform thing. It's crude but hey...it works. |
| ||
is system_ or CreateProcess() cross platform? |
| ||
both I think |
| ||
ty! |