Command line args if launched from terminal
Command line args if launched from terminal
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?
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
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
macOS Catalina 10.15.7
Re: Command line args if launched from terminal
Thanks Wolfram. But I am already doing a file mutex to determine if the application is already running.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
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
This is not 100% true, because if you run this inside a new terminal window you will get a new program running.MacOS allows only a single instance by default.
Code: Select all
/Applications/TextEdit.app/Contents/MacOS/TextEdit
macOS Catalina 10.15.7
Re: Command line args if launched from terminal
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.Wolfram wrote:This is not 100% true, because if you run this inside a new terminal window you will get a new program running.MacOS allows only a single instance by default.Only if you run the .app packet OSX will not open a second version of it.Code: Select all
/Applications/TextEdit.app/Contents/MacOS/TextEdit
Re: Command line args if launched from terminal
I think you should use the normal PureBasic CountProgramParameters() and ProgramParameter() commands for that.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Command line args if launched from terminal
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
macOS Catalina 10.15.7
Re: Command line args if launched from terminal
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?
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:
Code: Select all
open -a myApp.app --args params
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
I'm confused right now about what you want.coder14 wrote:Is there a way or are the parameters lost forever?
Do you mean that if you use
Code: Select all
open -a myApp.app --args params
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Command line args if launched from terminal
Yes!wilbert wrote:I'm confused right now about what you want.coder14 wrote:Is there a way or are the parameters lost forever?
Do you mean that if you useyou want the arguments to be passed to the instance that is already running ?Code: Select all
open -a myApp.app --args params
Re: Command line args if launched from terminal
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.
Edit:
Sorry, I overlooked in your first post that you already knew about -n
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
Sorry, I overlooked in your first post that you already knew about -n
Last edited by wilbert on Mon Mar 06, 2017 2:57 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Command line args if launched from terminal
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?
Do you want that all instances do the same or different things?
macOS Catalina 10.15.7
Re: Command line args if launched from terminal
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?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?
Re: Command line args if launched from terminal
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
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
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'
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Command line args if launched from terminal
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.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 ?
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.