Custom Clarify Classic Client command line parameters
Most of you know that there a bunch of command line options available for the Clarify Classic Client.
Some of the more common ones include:
- cbtrace
- CBDebugger
- clfy
- waggle
- debug
- debugCB
- msg
- nocache
- sqlhint
- sqllog
But did you also know you can pass your own parameters and evaluate them?
Lets take a simple example
Lets start clarify, passing in a case ID number. We’ll do this by coming up with our own custom URL format.
Custom URL Format? OMGWTFBBQ!
Everyone’s familiar with URL formats such as:
But we can also define custom URL formats, such as:
Not that it does anything, yet. But it looks cool, no?
Back to clarify.exe params
OK, so lets pass that as param to clarify.exe
From a command line, start clarify.exe with that custom URL as a param, like so:
OK, so that just starts clarify. What happens with that URL?
Well, at this point, nothing. Yet.
Lets make it do something with that param.
Initialize_app subroutine
In Clarify, the initialize_app subroutine (in ClearBasic) gets executed when the Clarify client starts up. So lets see if we can grab that param and do something with it.
First, we have our initialize_app subroutine, adding in a call to Process Command Line Arguments:
Public Sub initialize_app() Call ProcessCommandLineArgs() End Sub
Next, we have a subroutine to process the command line args:
Sub ProcessCommandLineArgs() 'Process any clarify URLS that were passed in on the command line '(such as clarify://case/12345) dim cmdLine as String dim url as String dim result as integer dim num as Integer dim listWords as new List dim pos as integer cmdLine = GetCommandLine(); pos = InStr(cmdLine, "clarify://") if pos >= 0 Then url = Mid$(cmdLine, pos) Call handle_clarify_url(url) End If End Sub
So, we need a function to GetCommandLine, and one to handle_clarify_url.
This *should* work to get the command line:
Function GetCommandLine() As String GetCommandLine = Command$ End Function
Notice that we’re using the Command$ statement built into BasicScript to get the command line arguments. But this doesn’t work (at least for me, in Clarify 11.5 on Win7 64-bit). YMMV.
Bummer.
Instead, we can do it using win32 calls, like so:
Declare Function lstrcpyn_long_string Lib "kernel32" Alias "lstrcpynA" (ByVal DestString As String, ByVal SourcePointer As Long, ByVal MaxLen As Long) As Long Declare Function lstrlen_long Lib "kernel32" Alias "lstrlenA" (ByVal SourcePointer As Long) As Long Declare Function GetCommandLine_long Lib "kernel32" Alias "GetCommandLineA" () As Long Declare Function parse_string(str_input as String, str_delim as String, _ int_count as Integer, lst_words as List) as Integer Function GetCommandLine() As String 'Get a pointer to process commandline as Long Dim ptrCommandLine As Long ptrCommandLine = GetCommandLine_long If ptrCommandLine > 0 Then 'GetCommandLine ok Dim Buffer As String, BufferLength As Long 'Get a length of the command line using Long pointer 'Returns the length without the zero terminating char BufferLength = lstrlen_long(ptrCommandLine) If BufferLength > 0 Then 'Allocate a space for the command line Buffer = Space(BufferLength + 1) 'Copy the command line to a buffer using Long + String pointers. ptrCommandLine = lstrcpyn_long_string(Buffer, ptrCommandLine, BufferLength + 1) 'The copy SHOULD be OK. Zero means some error, not enough of space If ptrCommandLine > 0 Then 'lstrcpyn 'Remove the zero terminator from the copied string Dim PosZero As Long PosZero = InStr(Buffer, Chr$(0)) If PosZero > 0 Then Buffer = Left(Buffer, PosZero - 1) GetCommandLine = Buffer End If 'If ptrCommandLine > 0 Then 'lstrcpyn End If 'If BufferLength > 0 Then End If 'If ptrCommandLine > 0 Then 'GetCommandLine ok End Function
Great!
Now that we have the command line, we can pass that string off to handle_clarify_url, where we’ll either open a new case form or open an existing case form.
Sub handle_clarify_url(url as String) dim result as integer dim num as Integer dim listWords as new List dim id as String dim objectType as String dim winName as String result = parse_string(url, "/", num, listWords) objectType = listWords.ItemByIndex(2) id = listWords.ItemByIndex(3) if objectType = "case" Then if id = "new" then App.NewCase else show_case id end if end if End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Show an Existing Case ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub show_case(case_id As String) Dim t_ret As New BulkRetrieve ' Structure to query the DB Dim case_list As List ' List of returned cases Dim case_rec As Record ' One returned case ' Query for the case ' Get the results t_ret.SimpleQuery 0, "case" t_ret.AppendFilter 0, "id_number", cbEqual, case_id t_ret.RetrieveRecords Set case_list = t_ret.GetRecordList(0) ' If case not found, error message ' Else, post the case If case_list.Count = 0 Then App.MsgBox "Customer keyed in case " + case_id + ", but that case is not found in the database." Else Set case_rec = case_list.ItemByIndex(0) App.ShowCase case_rec End If End Sub
Lets see it work – Open an existing case
command: clarify.exe clarify://case/149
Lets see it work – Open a new case
command: clarify.exe clarify://case/new
OK, that’s some pretty cool stuff!
Code
I realize there’s a bunch of code there. Don’t worry, I’ve shared it all.
The entire code is available on github: https://gist.github.com/gsherman/2839349
What now?
Well, now that we’ve proved that we can pass in a param to Clarify and do something with it, lets do something more interesting.
But that’ll have to happen in the next post. Stay tuned. And stay thirsty.
Rock on.