Archive for the 'Visual Basic' Category

How to avoid VBScript regular expression gotchas

VBScript regular expressions are slightly troublesome, though they certainly help turn VBScript into less of a joke when it comes to text processing. The syntax lacks some of the niceties of Perl or .NET regexes, but is complete enough to be very useful. This article shows you how to avoid potentially serious problems, and explains an undocumented feature.

Undocumented and incorrect behavior

  1. The documentation is incomplete. The RegExp object has an undocumented property, Multiline, which affects pattern matching using the . metacharacter. This property’s default value is False, so . matches every character except a newline by default. When Multiline is True, the meaning of the . metacharacter is different; it then matches every character including a newline. This is the same behavior you will find in other languages, such as Perl and .NET.
  2. Backslashed special characters do not work correctly inside brackets. For example, it ought to be possible to match across newlines with the patterns [.\n]* and [.\s]*, but this prevents the pattern from matching anything at all, even when no newlines are involved.

How to avoid memory leaks

There is a memory-leak bug which has been reported elsewhere on the Internet. An expression with more than 10 subexpressions in Global mode can leak memory. To avoid this bug, don’t use a pattern with more than 10 subexpressions if the object’s Global property is set to True.

Documentation links

Here are two links to the Microsoft VBScript RegExp documentation on MSDN:

  1. VBScript Regular Expression Syntax
  2. The VBScript RegExp object
Technorati Tags:No Tags

You might also like:

  1. Browser variations in RegExp.exec()
  2. Bash parameter expansion cheatsheet
  3. JavaScript regular expression toolkit
  4. How to use the Visual SourceSafe automation interface
  5. How to create input masks in HTML

How to create a VB6 console program

Visual Basic 6 programs can be run as console programs, if configured correctly. There are four basic requirements to create a useful console program in VB6:

  • Remove all forms and dialogs
  • Provide access to standard input, output, and error streams
  • Provide access to the command-line arguments
  • Re-link the program for the Windows Console subsystem

Remove forms and dialogs

By default, a VB6 project has “forms” or “windows,” which can contain application code. When running a program in the console, you don’t want anything but the console, ever. When you create a VB6 project, just remove all the forms from it, and add a module. You need at least one module, which will contain a subroutine called Main(). When you look at the project properties, you will see the “startup object” set to Sub Main.

There is still a possibility that some dialogs can be created. For example, a runtime error will pop up a dialog. To avoid this, choose the “Unattended Execution” checkbox in the Project Properties dialog. By default, dialogs will now be shunted to the Windows Event Log. You can control this with the App.StartLogging method, if desired.

Get access to stdio streams

A console app usually needs to work with standard input and output. There are at least two ways to accomplish this: by using the Win32 API, and by using the Scripting.FileSystemObject’s text streams. In either case, the streams will not be available when running the app in the debugger, so it may be a good idea to create a wrapper around the calls and only try to use them if they are available. The Win32 API calls are easy to use, and I have posted sample code for your reading pleasure. The Scripting.FileSystemObject’s text streams are equally easy to use. Microsoft’s FileSystemObject documentation should help you get started on those. You will need to add a reference to “Microsoft Scripting Runtime” in your project to use the FileSystemObject.

Get access to command-line arguments

The text of the command-line arguments with which the VB6 console app was invoked is available by calling the Command() function, but it is non-trivial to parse the text into individual arguments such as those C programmers are used to using. It’s not impossible; depending on your needs you may be able to use regular expressions, the Split() function, a tokenizer (finite state machine), or invoke the Win32 API again by calling the CommandLineToArgvW function. The latter uses Unicode, so you will need to convert between VB strings and Unicode. The StrConv() function will help here, but on the reverse conversion you will need to do a bit more. Google will provide many links to examples of using these two functions for this job.

Re-link the program for the Windows Console subsystem

There seems to be no option in the VB project properties or compile options to do this automatically when making the program, so you will need to re-link after compilation. If you don’t do this, your program will not run correctly. The standard streams will not be available, for one thing. Fortunately, it is quite easy to do:

"C:\Program Files\Microsoft Visual Studio\vb98\LINK.EXE" /EDIT /SUBSYSTEM:CONSOLE <yourfile.exe> (this code should all be on one line).

A handy shortcut is to create a batch file with the command in it. You can then drag your .EXE file onto the batch file. Assuming LINK.EXE is in your path, the following will work:

LINK.EXE /EDIT /SUBSYSTEM:CONSOLE %1

Don’t name the batch file “link.bat” or it will call itself! Another of Microsoft’s insecure default behaviors.

Acknowledgements

I have gleaned this code from all over the Internet. Very little of it is my own.

Technorati Tags:No Tags

You might also like:

  1. How to use the Visual SourceSafe automation interface

How to use the Visual SourceSafe automation interface

Microsoft Visual SourceSafe provides an automation interface that can be used from within VBScript, VB6 and other languages. This article lists the options for automating SourceSafe, provides links to documentation, and discusses some bugs that are impossible to work around.

Documentation

I am in the unenviable position of needing to write a VBScript program to interact with SourceSafe. Unfortunately the documentation is hard to find and not at all clear or user-friendly. Here are the two links I find useful:

Bugs

I notice a number of bugs. For instance, no matter what I do, I cannot get the IVSSItem.Get or IVSSItem.CheckOut methods working in VBScript (they do work in VB6). I just get strange errors about “Type mismatch” or “Invalid DOS path:” depending on how I call the method. I see others on the web have had the same problem, but no solution. It’s pretty miserable.

Command-line interface

There is a command-line tool, SS.EXE, but it is almost totally unusable for scripting purposes. It has strange dependencies on the Visual SourceSafe client program, requires environment variables instead of accepting command-line arguments, and does very frustrating things that cannot be overriden easily. For example, the “get” command gets the file into the current directory even if you specify a subdirectory; in other words, the command ss Get dir/file.txt will get the file into the current directory, not dir. This is a shame, as this is the command I really want to use because it doesn’t work via the automation interface in VBScript.

Technorati Tags:No Tags

You might also like:

  1. How to create a VB6 console program
  2. How to avoid VBScript regular expression gotchas
  3. How to exploit an insecure order of access to resources
  4. How to flatten hierarchies with awk
  5. Three updated tools in MySQL Toolkit