ExecFile with Arguments?

BlitzMax Forums/BlitzMax Programming/ExecFile with Arguments?

Chroma(Posted 2009) [#1]
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?


SebHoll(Posted 2009) [#2]
Have you tried OpenUrl()?


Chroma(Posted 2009) [#3]
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.


SebHoll(Posted 2009) [#4]
That's weird. Hmmmm, if you are OK with the new executable terminating when your own program closes, try CreateProcess().


Chroma(Posted 2009) [#5]
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.


SebHoll(Posted 2009) [#6]
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


Chroma(Posted 2009) [#7]
I'm kneedeep in the system.bmx code and I'm gonna fix this...with BEER in hand!!


Chroma(Posted 2009) [#8]
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...


Chroma(Posted 2009) [#9]
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.


_Skully(Posted 2009) [#10]
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


N(Posted 2009) [#11]
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.


TaskMaster(Posted 2009) [#12]
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.


TaskMaster(Posted 2009) [#13]
This is the thread:

http://www.blitzmax.com/Community/posts.php?topic=69287#928765


Chroma(Posted 2009) [#14]
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.


Flemmonk(Posted 2009) [#15]
You obviously didn't look hard enough!


GaryV(Posted 2009) [#16]
Chroma, all you need to do is use the standard API call.


Brucey(Posted 2009) [#17]
all you need to do is use the standard API call.

I tried it, but it wouldn't even compile on my Mac...


Jason W.(Posted 2009) [#18]
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


Chroma(Posted 2009) [#19]
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)



Flemmonk(Posted 2009) [#20]
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?


Chroma(Posted 2009) [#21]
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.


JoshK(Posted 2009) [#22]
CreateProcess("myprogram.exe arguments")


Chroma(Posted 2009) [#23]
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.


Brucey(Posted 2009) [#24]
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??


TaskMaster(Posted 2009) [#25]
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.


BlitzSupport(Posted 2009) [#26]

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



TaskMaster(Posted 2009) [#27]
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")


Chroma(Posted 2009) [#28]
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.


TaskMaster(Posted 2009) [#29]
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.


N(Posted 2009) [#30]
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".


Brucey(Posted 2009) [#31]
Why are you writing Chr(34)

Because Chr(34) is only 1 character, whereas ~q is 2 ?


N(Posted 2009) [#32]
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.


Chroma(Posted 2009) [#33]
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.


Brucey(Posted 2009) [#34]
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.


TaskMaster(Posted 2009) [#35]
I didn't know about the ~q. That is why I used Chr(34).


Chroma(Posted 2009) [#36]
@ 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.


N(Posted 2009) [#37]
No, Chroma, Chr(34) is bad. Baaaaad.


Brucey(Posted 2009) [#38]
I mean I put a "/" between the currentdir and MyServer.eve:

Well, on Windows you probably want to be using \ instead of / ?


Perturbatio(Posted 2009) [#39]
windows should support the forward slash as well


Chroma(Posted 2009) [#40]
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.


beanage(Posted 2009) [#41]
is system_ or CreateProcess() cross platform?


Me.32(Posted 2009) [#42]
both I think


beanage(Posted 2009) [#43]
ty!