twinBASIC: Setting Cmd Line Args in Debug Mode

The VB6 Command$() function returns command line arguments in twinBASIC. But, for now, we still need a workaround to set cmd line args while debugging.

twinBASIC: Setting Cmd Line Args in Debug Mode

UPDATE [2021-05-31]: This feature is now natively supported in twinBASIC.

This option is now available within the build configurations screen.

In twinBASIC, you access command line arguments the same way as in VB6 and VBA, via the Command$ function:

MsgBox "Command line arguments: " & Command$

As with other similar functions, we can also call the function without the trailing dollar sign.  The only difference is in the return type.  When called with the dollar sign, the return type is String; without it, the return type is Variant.

Setting command line arguments while debugging

Most languages have support for setting command line arguments for use while debugging.  twinBASIC will likely support that in the future, probably with a Build Configuration setting.  Until then, it would be nice to be able to set those values in code so that we don't have to build our project and then run the executable from a cmd prompt or Powershell window just to test the command line.

Version 1: The Starting Point

The simplest way to do that would be to overload the Command function with our own version.  For example, we could do this:

Public Function Command() As Variant
    Return "/TwitterHandle=NoLongerSet"
End Function

There are a couple of problems with this version.  First, I prefer the strongly-typed version of the Command$ function with the trailing dollar sign.  Also, if we do pass a command line argument to the compiled .exe, it will be ignored.

Version 2: A Major Improvement

In this version, we address my earlier concerns by changing the name of the function from Command to Command$ and changing the return type from Variant to String.  

We also check to see if an actual command line argument was passed to the application.  If so, we return that value instead of our default debugging value:

Public Function Command$() As String
    If Len(VBA.Interaction.Command$) > 0 Then
        Return VBA.Interaction.Command$
    End If
End Function

At this point you may be thinking, "Why not support both versions of the function: the Variant Command and the String Command$?"  The short answer is...because we can't.  If we try, we get a compilation error:

There is one other thing that is nagging me about this solution.  If we release this application and another user runs it without providing any command line parameters, they will get our default debugging values.  Now, that may be what we want, but it's probably not.

I could not find any sort of flag to indicate how the application was launched.  Ideally, there would be some way to check to see if VS Code had launched our application.  In that case, we would fall back on our debugging values for the command line arguments.

If, instead, some other application had launched our application–such as cmd, Powershell, or explorer–then our Command$ function would return an empty string.  Since I'm not aware of a simple way to achieve this (perhaps some combination of Windows APIs would do it), I'm going to take the 80/20 approach and solve the problem for the most common situation.

Version 3: Preventing debug code from leaking into production

Generally speaking, we will be running our application in production on a different device than the one on which we are developing.  A good bit of defensive programming is to make sure our debugging code does not leak into our production environment.

A simplistic algorithm for checking if we are in a development environment is to see if we are running the code on our development machine.  And, the simplest way to do this is by checking the ComputerName environment variable:

Final thoughts

Admittedly, this is not the most robust solution.  However, I don't think it's worth doing much more to deal with corner cases right now since there is hopefully an official solution in the offing.

All original code samples by Mike Wolfe are licensed under CC BY 4.0