What is the solution for Linux for " function returns the passed arguments to a Desktop application as a String array"
What is the problem?
Get @Jeremy Cowgar 's Option Parser from here:
https://github.com/jcowgar/xojo-option-parser
It contains a function that will properly return the command line arguments on all platforms, and the classes will let you properly handle them as a bonus.
For linux , the applications can not be invoked with parameters like the console applications.
For windows, i use like this :
[b] if TargetWin32
declare function GetCommandLineW lib "kernel32.dll" () as Ptr
declare function CommandLineToArgvW lib "shell32.dll" (lpCmdLine As Ptr, ByRef pNumArgs As Integer) As Ptr
declare sub LocalFree Lib"kernel32.dll" (p as Ptr)
dim cl as Ptr = GetCommandLineW()
dim n as Integer
dim argList as Ptr = CommandLineToArgvW (cl, n)
for idx as Integer = 0 to ..
dim mb as MemoryBlock = argList.Ptr(idx*4)
dim len as Integer
while mb.UInt16Valu(len) <> 0
len = len + 2
wend
dim s as String = mb.StringValue(0,len)
args.Append s
next
[/b]
I would like the solution for linux,
Thanks
You can start your app from the Linux terminal with:
/path/to/MyApp params
I have another application used with my application and that why I want this command line . for windows works very well with the above code . and I need code as above for linux
Please see my earlier post about the Option Parser. The code you seek is there.
What you could do is to use a Console app as launcher that passes the arguments to the main app through IPCSocket, or simply by creating a small text file that the main app will read.
@ Kem Tekinay I still use RB , but not Xojo
Kem Tekinay
your earlier post about the /path/to/MyApp params is interesting
but how to get the parameters on Linux? thanks
The code you need is in the project I mentioned. I’m not in a position to copy and paste it, but you can download it, open it, and copy what you need, even in the latest RB. The classes themselves may even work in the latest RB, but I don’t think we ever tested that.
Shared Function CommandLineArgs() As String()
// Return an array of command-line arguments
const kDebugDeclares = false
dim args() as string
#if DebugBuild and not kDebugDeclares then
//
// Not perfect, but will emulate what you'll get in the built app
//
args = ParseStringValue(System.CommandLine)
#elseif TargetMacOS then
const kCocoaLib = "Cocoa.framework"
declare function NSClassFromString lib kCocoaLib (aClassName as CFStringRef) as Ptr
declare function defaultCenter lib kCocoaLib selector "processInfo" (class_id as Ptr) as Ptr
declare function arguments lib kCocoaLib selector "arguments" (obj_id as Ptr) as Ptr
declare function m_count lib kCocoaLib selector "count" (obj as Ptr) as UInteger
declare function objectAtIndex lib kCocoaLib selector "objectAtIndex:" (theArray as Ptr, idx as Integer) as CFStringRef
static c as Ptr = defaultCenter(NSClassFromString("NSProcessInfo"))
dim nsArrayRef as Ptr = arguments(c)
dim ub as integer = m_count(nsArrayRef) - 1
for i as integer = 0 to ub
dim s as string = objectAtIndex(nsArrayRef, i)
args.Append s
next
#elseif TargetWin32 then
//
// Windows and Linux code from Thomas Tempelmann
//
declare function GetCommandLineW lib "kernel32.dll" () as Ptr
declare function CommandLineToArgvW lib "shell32.dll" (lpCmdLine As Ptr, ByRef pNumArgs As Integer) As Ptr
declare sub LocalFree Lib "kernel32.dll" (p as Ptr)
dim cl as Ptr = GetCommandLineW()
dim n as Integer
dim argList as Ptr = CommandLineToArgvW (cl, n)
for idx as Integer = 0 to n-1
dim mb as MemoryBlock = argList.Ptr(idx*4)
// mb points to a UTF16 0-terminated string. It seems we have to scan its length ourselves now.
dim len as Integer
while mb.UInt16Value(len) <> 0
len = len + 2
wend
dim s as String = mb.StringValue(0,len).DefineEncoding(Encodings.UTF16)
s = s.ConvertEncoding(Encodings.UTF8)
args.Append s
next
LocalFree(argList)
#elseif TargetLinux then
// read from "/proc/self/cmdline", each item is 0-terminated
const SystemLib = "libc.so"
declare function open lib SystemLib (path as CString, flags as Integer) As Integer
declare function read lib SystemLib (fd as Integer, data as Ptr, n as Integer) as Integer
// first, read the entire cmdline into a string
dim fd as Integer = open ("/proc/self/cmdline", 0)
dim s as String
do
dim mb as new MemoryBlock(1000)
dim n as Integer = read (fd, mb, mb.Size)
s = s + mb.StringValue (0, n)
if n < mb.Size then exit
loop
args = s.Split(Chr(0))
call args.Pop // remove last array item because of extra 00 byte at end of string
for i as integer = 0 to args.Ubound
dim thisArg as string = args(i)
if Encodings.UTF8.IsValidData(thisArg) then
args(i) = thisArg.DefineEncoding(Encodings.UTF8)
else
args(i) = thisArg.DefineEncoding(Encodings.ISOLatin1)
end if
next
#endif
return args
End Function
Kem Tekinay
I’ll test it. thanks a lot, see you
Except System.CommandLine only gives you the raw string without quotes. If you start your app with something like this:
myapp display ‘this is some text’
System.CommandLine would contain “display this is some text”, and that’s essentially useless.
OK
Seems like that’s the linux shell resolving things on the command line. Try escaping the quotes?
[quote=202076:@Kem Tekinay]Except System.CommandLine only gives you the raw string without quotes. If you start your app with something like this:
myapp display ‘this is some text’
System.CommandLine would contain “display this is some text”, and that’s essentially useless.[/quote]
Under Linux Mint, I get the app path and then
display 'this is some text'
Looks to me extremely easy to parse. But I don’t know, maybe I should change glasses…
This is in a compiled app? It’s different in the debug build.
Indeed the quotes disappear in the build.
Should not a bug report be filed ?