Page 1 of 2
Command line args if launched from terminal
Posted: Sat Mar 04, 2017 6:02 pm
by coder14
MacOS does not launch multiple instances of the same app by default. If an associated file is double-clicked in Finder when an instance of the app is already running we can get the file name with this callback routine from Fred:
http://forums.purebasic.com/english/vie ... 0d#p391284
But if a second instance is started from Terminal with the "open -a" command with "--args" Fred's routine does not get the parameters and the second instance will be shut down (unless the "open -n" flag is used). Is there any way to get the parameters if the app is launched from Terminal?
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 1:18 pm
by Wolfram
Maybe you can do it like this:
Code: Select all
Global Window_0, Button_0
Procedure isAlreadyRunning()
thisApp =CocoaMessage(0,0, "NSRunningApplication currentApplication")
thisAppName =CocoaMessage(0, thisApp, "localizedName")
If thisAppName
thisName.s =PeekS(CocoaMessage(0, thisAppName, "UTF8String"), -1, #PB_UTF8)
EndIf
NSArray_apps = CocoaMessage(0,CocoaMessage(0,0,"NSWorkspace sharedWorkspace"),"runningApplications")
If NSArray_apps
count = CocoaMessage(0, NSArray_apps, "count")
For i = 0 To count -1
app =CocoaMessage(0, NSArray_apps, "objectAtIndex:",i)
If app
appName = CocoaMessage(0, app, "localizedName")
If appName
Name.s =PeekS(CocoaMessage(0, appName, "UTF8String"), -1, #PB_UTF8)
If Name =thisName
result +1
EndIf
EndIf
EndIf
Next
EndIf
ProcedureReturn result -1
EndProcedure
Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Button_0 = ButtonGadget(#PB_Any, 160, 50, 130, 25, "quit")
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
Case #PB_Menu_Quit
ProcedureReturn #False
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case Button_0
ProcedureReturn #False
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
If isAlreadyRunning()
MessageRequester("Message", "App is already running")
Else
OpenWindow_0()
Repeat
event = WaitWindowEvent()
Until Window_0_Events(event) = #False
EndIf
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 2:28 pm
by coder14
Wolfram wrote:Maybe you can do it like this:
Code: Select all
Global Window_0, Button_0
Procedure isAlreadyRunning()
thisApp =CocoaMessage(0,0, "NSRunningApplication currentApplication")
thisAppName =CocoaMessage(0, thisApp, "localizedName")
If thisAppName
thisName.s =PeekS(CocoaMessage(0, thisAppName, "UTF8String"), -1, #PB_UTF8)
EndIf
NSArray_apps = CocoaMessage(0,CocoaMessage(0,0,"NSWorkspace sharedWorkspace"),"runningApplications")
If NSArray_apps
count = CocoaMessage(0, NSArray_apps, "count")
For i = 0 To count -1
app =CocoaMessage(0, NSArray_apps, "objectAtIndex:",i)
If app
appName = CocoaMessage(0, app, "localizedName")
If appName
Name.s =PeekS(CocoaMessage(0, appName, "UTF8String"), -1, #PB_UTF8)
If Name =thisName
result +1
EndIf
EndIf
EndIf
Next
EndIf
ProcedureReturn result -1
EndProcedure
Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Button_0 = ButtonGadget(#PB_Any, 160, 50, 130, 25, "quit")
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
Case #PB_Menu_Quit
ProcedureReturn #False
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case Button_0
ProcedureReturn #False
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
If isAlreadyRunning()
MessageRequester("Message", "App is already running")
Else
OpenWindow_0()
Repeat
event = WaitWindowEvent()
Until Window_0_Events(event) = #False
EndIf
Thanks Wolfram. But I am already doing a file mutex to determine if the application is already running.
What I need is to get the command parameters from instances attempting to launch from Terminal but keep getting shut down because MacOS allows only a single instance by default.
How would I get the command line arguments when a second instance is being launched with arguments but gets shut down by MacOS?
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 3:25 pm
by Wolfram
MacOS allows only a single instance by default.
This is not 100% true, because if you run this inside a new terminal window you will get a new program running.
Code: Select all
/Applications/TextEdit.app/Contents/MacOS/TextEdit
Only if you run the .app packet OSX will not open a second version of it.
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 4:04 pm
by coder14
Wolfram wrote:MacOS allows only a single instance by default.
This is not 100% true, because if you run this inside a new terminal window you will get a new program running.
Code: Select all
/Applications/TextEdit.app/Contents/MacOS/TextEdit
Only if you run the .app packet OSX will not open a second version of it.
But how do we get the command line parameters if the app is started in Terminal with "open -a" options? The app does not open a new instance but the command line parameters are lost.
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 4:33 pm
by wilbert
I think you should use the normal PureBasic CountProgramParameters() and ProgramParameter() commands for that.
Re: Command line args if launched from terminal
Posted: Sun Mar 05, 2017 5:07 pm
by Wolfram
But how do we get the command line parameters if the app is started in Terminal with "open -a" options? The app does not open a new instance but the command line parameters are lost.
Code: Select all
;read command line parameters
If CountProgramParameters()
While argCount <= CountProgramParameters()
argValue.s = ProgramParameter(argCount)
If Left(argValue, 1) = "-" And Len(argValue) > 1
argValue = LCase( Right(argValue, Len(argValue) -1) )
Select argValue
Case "p"
;Do something
Default
PrintN ("read "+argValue)
EndSelect
EndIf
argCount +1
Wend
EndIf
Re: Command line args if launched from terminal
Posted: Mon Mar 06, 2017 8:51 am
by coder14
Thank you for your answers. CountProgramParameters and ProgramParameter works in the first instance. But how do i get the parameters from the second instance.
Starting my app from
Terminal:
1. I launch my app (from Terminal or Finder doesn't matter). While this instance is running:
2. I launch another instance of my app from
Terminal like this:
The
second instance is able to get the "params" with CountProgramParameters and ProgramParameter. How is it going to pass the "params" to the
first instance?
The same scenario from
Finder works differently:
1. I launch my app (from Terminal or Finder doesn't matter). While this instance is running:
2. I launch another instance of my app from
Finder (by double-clicking an associated
file or dragging an associated
file onto the myApp.app icon in
Finder).
3. Using the
PB_Gadget_SetOpenFinderFiles(Callback) function I am able to get the name of the
file that launched the app.
Is there a way or are the parameters lost forever?
Re: Command line args if launched from terminal
Posted: Mon Mar 06, 2017 9:09 am
by wilbert
coder14 wrote:Is there a way or are the parameters lost forever?
I'm confused right now about what you want.
Do you mean that if you use
you want the arguments to be passed to the instance that is already running ?
Re: Command line args if launched from terminal
Posted: Mon Mar 06, 2017 9:14 am
by coder14
wilbert wrote:coder14 wrote:Is there a way or are the parameters lost forever?
I'm confused right now about what you want.
Do you mean that if you use
you want the arguments to be passed to the instance that is already running ?
Yes!

Re: Command line args if launched from terminal
Posted: Mon Mar 06, 2017 9:53 am
by wilbert

I searched a bit on the internet but so far I haven't found a solution.
You can of course open a new instance with -n but that probably isn't what you want.
Code: Select all
open -n -a myApp.app --args params
Edit:
Sorry, I overlooked in your first post that you already knew about -n
Re: Command line args if launched from terminal
Posted: Mon Mar 06, 2017 11:45 am
by Wolfram
Can you give us a function description of what do you exactly want?
Do you want that all instances do the same or different things?
Re: Command line args if launched from terminal
Posted: Tue Mar 07, 2017 8:12 am
by coder14
Wolfram wrote:Can you give us a function description of what do you exactly want?
Do you want that all instances do the same or different things?
By default Mac does not allow multiple instances of an app to run concurrently. If an instance is already running, trying to launch it again using the command-line "open -a myapp.app --args NEWPARAMS" from Terminal will not work. How do I get NEWPARAMS from the instance that is being shut down?
Re: Command line args if launched from terminal
Posted: Tue Mar 07, 2017 8:32 am
by wilbert
I don't know if it is even possible what you want.
Did you consider alternative options like using AppleScript to tell to your already running application what you want it to do ?
From the terminal you would need to use osascript if you would do it this way. Like
Code: Select all
osascript -e 'tell app "Finder" to make new Finder window'
This topic from deseven explains how to make your application respond to AppleScript if you are interested
http://www.purebasic.fr/english/viewtop ... 19&t=66750
Re: Command line args if launched from terminal
Posted: Tue Mar 07, 2017 8:51 am
by coder14
wilbert wrote:I don't know if it is even possible what you want.
Did you consider alternative options like using AppleScript to tell to your already running application what you want it to do ?
The running instance would not even know that a second instance is being launched. But when the second instance is shut down we will lose the file that it is trying to open.
When this is done through Finder it works - double-clicking on an associated file would not launch a second instance but the file name can be gotten through PB_Gadget_SetOpenFinderFiles(Callback).
OTOH running "open -a myapp.app --args file2Open.ext" in Terminal when an instance of the app is already running would also not launch a second instance but there is no way of getting the passed parameter "file2Open.ext".
In Windows I use PB's parameter functions then SendMessageTimeout to the running instance with a custom message and #WM_COPYDATA then send/receive the parameters through COPYDATASTRUCT.