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.
UPDATE [2021-05-31]: This feature is now natively supported in twinBASIC.
In twinBASIC, you access command line arguments the same way as in VB6 and VBA, via the
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$ 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:
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.