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.


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


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
          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
  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."
     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!


I realize there’s a bunch of code there. Don’t worry, I’ve shared it all.

The entire code is available on github: 

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.