AddDataFile filespec
Copies a file into the output project’s main directory and includes the file
in the VB.NET project, so that it is automatically copied to the output folder when
the project is compiled. It is useful to copy images, Access MDB files, and other
data files into the target project. The filespec argument is mandatory:
it must be a path relative to the VB6 project’s folder (can’t be an absolute path),
can contain wildcards, and must be enclosed in double quotes if it includes spaces:
AddDisposableType typename
Tells VB Migration Partner that a VB6 class is to be considered as a disposable
type and be dealt with in a special way when a variable of this type is in the scope
of an AutoDispose pragma. It is useful with COM objects that require finalization,
for example objects that open a database connection. (Notice that VB Migration Partner
recognizes as disposable ADODB objects such as Connection and Recordset.) The typename
argument is mandatory and must include the type library name:
AddImports namespace [,explicit]
Imports a .NET namespace at the project- or file-level. It is useful together with
an AddReference pragma, to make all types of the referenced library accessible from
the current project. The namespace argument is mandatory and must be enclosed
in double quotes if it includes spaces:
If you specify True in the second argument, the namespace is imported at the file-level
by means of an explicit Imports statement. For example the following pragma:
generates the following statement at the top of the file where the pragma resides:
Imports ADODB
Even if it is rarely necessary or desirable, you can even generate explicit Imports
statements in all the files in the projects by using an explicit project scope:
It’s worth noticing that the AddImports pragma has the added effect to drop
all the imported namespace off type names, regardless of whether the namespace was
imported at the project- or file-level. This feature helps producing more concise
and readable code.
AddLibraryPath path, recurse, searchPattern
This pragma requires VB Migration Partner Enterprise edition
Specifies folder where VB Migration Partner can search DLLs and type libraries that
have been already converted to VB.NET. The path argument is the absolute
name of a directory; recurse is a Boolean that specifies whether the search
must be extended to subfolders (if False or omitted, the search is limited to the
directory specified in the first argument); searchPattern allows you to
restrict the effect of this pragma to certain files.
The third argument is a regular expression that is applied against the base name
of each file in the specified directory (or directory tree), that the file name
without path and without extension (the extension is assumed to be “.dll”).
For example, the following pragma:
would include only the DLL files whose name starts with “CodeArchitects.”.
You can apply the AddLibraryPath pragma only by storing it in a *.pragmas file.
We suggest that you use the special file named VBMigrationPartner.pragmas, which
you can conveniently share among all the projects of a complex application.
An important note: if you are migrating a VB6 project group, this pragma should
be included in the *.pragmas file that accompanies each project, regardless of whether
that specific project uses the classes defined in the DLLs the pragma points to.
If the *.vbp files are all located in the same folder, you can use one single VBMigrationPartner.pragmas
file in that directory.
AddSourceFile filename [, addaslink]
This pragma requires VB Migration Partner Enterprise edition
Adds a VB.NET source file to the project generated by VB Migration Partner. The
filename argument is the absolute path of a *.vb source file; the second
optional parameter is False (or omitted) if the file is copied to the output folder
and included in the VB.NET project as a regular file, True if the file is added
as a link an existing file. The pragma recognizes form and usercontrol source files
and automatically imports the *.Designer.vb and *.resx files, if they exist.
If the source file being imported requires a reference to an external DLL, you must
provide an AddReference pragma; if the source file being imported assumes a project-level
Imports, you must provide a suitable AddImports pragma. These pragma must be included
in one of the original VB6 files:
AddReference asmPathOrName
Include a reference to a .NET assembly in the VB.NET project being created. It is
useful when the code you inject by means of InsertStatement pragmas requires a .NET
assembly that isn’t automatically referenced by default, for example System.Data.OracleClient.
The argument is mandatory, must be either the assembly's absolute file path or the
assembly's display name, and must be enclosed in double quotes if it includes spaces:
You typically specify the assembly’s display name for assemblies stored in the GAC.
ApplyRenameRules xmlfile
This pragma requires VB Migration Partner Enterprise edition
Specifies that VB Migration Partner should apply the rename rules contained in the
specified XML file, or in the default RenameRules.xml file stored in the install
folder:
This pragma can be specified in both a *.pragmas file or in source code, however
it affects all the projects in the solution being migrated.
For more information about renaming rules, see the
Renaming program members section.
AssemblyKeyFile filename.snk, delaysign
This pragma requires VB Migration Partner Enterprise edition
Signs the VB.NET assembly that results from the conversion, using the specified
.snk file. The filename.snk argument is the complete (absolute) path of
the .snk file that contains the public/private key pair; delaysign is a
Boolean that indicates whether the assembly must be delay-signed (default is False).
Using this pragma is equivalent to tick the “Sign the assembly” option
in the Signing tab of the My Project designer after the migration.
BinaryCompatibility force
This pragma requires VB Migration Partner Enterprise edition
Determines whether the migrated VB.NET project should preserve binary compatibility
with the COM component written in VB6. If the optional argument is False or omitted,
then compatibility is enforced only if the original VB6 project specified binary
compatibility; if the argument is True, then compatibility is enforced in any case.
When this pragma is active, VB Migration Partner generates a ComClass attribute
for each public class in the generated VB.NET project; this attribute specifies
the GUIDs of the original coclass, class interface, and event interface of the original
VB6 class. In addition, a project-level Guid attribute in AssemblyInfo.vb is generated
so that the .NET assembly has same GUID as the original type library. Finally, the
Register for COM Interop setting is enabled in the MyProject property page. The
neat effect of all these operations is that the .NET DLL is fully compatible with
the original COM DLL and all existing VB6/COM clients can continue to work as before
but use the new .NET DLL instead. (No recompilation is needed.)
By default, VB Migration Partner uses the COM DLL specified as the binary-compatible
DLL for the original VB6 project. (This is the DLL selected in the Component tab
of the Project Properties dialog box in the VB6 IDE.) If the original VB6 project
doesn’t specify binary compatibility (but the force argument is True)
then VB Migration Partner uses the output DLL to extract all existing GUIDs.
This pragma is ignored and no warning message is emitted if the VB6 project type
isn’t ActiveX DLL or if VB Migration Partner can’t find a COM DLL to
be used to extract coclass and interface GUIDs.
As a side-effect of this pragma, all public fields in public classes are rendered
as properties: this is necessary because public fields aren’t made visible
to COM clients by the ComClass attribute. In addition, if the field was declared
using As New, code is generated to preserve the auto-instancing semantics, regardless
of whether the field is under the scope of an AutoNew pragma. The effect is therefore
similar to the AutoProperty pragma, except that the BinaryCompatibility pragma affects
only fields in public classes inside ActiveX DLL projects.
EnableAppFramework mainform, splashform, visualstyles, shutdownmode, singleinstance
Enables the VB.NET application framework feature. The parameter passed to this pragma
correspond to the settings you can find in the Application tab of the My Project
designer in Visual Studio. The mainform argument is the name of the startup
form and is the only mandatory parameter for this pragma; splashform is
the name of the splash form, if any; visualstyles is True if you want to
enable Windows XP styles (the default is False); shutdownmode is 0 (the
default) if the application exits when the main form closes or 1 if the application
exits when all forms close; singleinstance is True if you want to prevent
multiple instances of this application (the default is False).
For example, the following pragma sets frmMain as the main form, frmSplash as the
splash screen form, enables XP visual styes and forces the application to close
only when all loaded forms are closed:
You should use this pragma only in standard EXE projects. When this pragma is specified,
the Sub Main form is ignored (if the application has one).
ImportTypeLib typelibfilename, tlbimpcommand, assemblyname, copytoprojectfolder
Specify the command line to be passed to the TlbImp.exe tool when importing a type
library. typelibfilename is the name of the .dll or .tlb file to be imported
(can be just the file name or the complete file path); tlbimpcommand is
the complete command that must be passed to the TlbImp.exe tool.
The third and fourth arguments are optional and are taken into account only if the
tlbimpcommand argument starts with a "@" character (see later).
Notice that you need to specify the entire path in the first argument only if the
current VB6 application uses two distinct type libraries with same file name:
This pragma is necessary when VB Migration Partner fails to correctly locate the
type library to be imported or any of the *.dll or *.tlb files such a type library
depends on, or when you need to specify any additional option for the TlbImp.exe
tool, such as when you want to sign the imported assembly with a strong name. Notice
that VB Migration Partner uses this pragma only to correctly resolve a reference
to a type library: the type library is actually imported in the current project
only if it was referenced by the original VB6 project.
You can apply this pragma only by storing it in a *.pragmas file. We suggest that
you use the special file named VBMigrationPartner.pragmas, which you can conveniently
share among all the projects of a complex application. (As explained above, a type
library is effectively imported only if it is referenced by the original VB6 project
and this pragma only teaches VB Migration Partner how the type library must be imported.)
As a special case, if the second argument starts with a “@” character
it is interpreted as the path of a .NET assembly that is equivalent to the original
type library. This syntax variation is useful in two cases: First, if you have already
(manually) converted the type library and have obtained the corresponding .NET assembly;
second, if the author of the original type library has provided a Primary Interop
Assembly for the type library and VB Migration Partner fails to correctly locate
such a PIA. Here’s an example of this technique
If the second argument begins with the “@” character, then the assemblyname
optional argument should be specified and should be equal to the name of the assembly.
This name is usually equal to the assembly’s root namespace, but it can also
be a different string. Specifying this value allows VB Migration Partner to determine
whether the .NET DLL should be added as a reference for the project being migrated,
without having to actually load all the assemblies in all folders referenced by
the project itself.
For example, assume that you have already migrated a VB6 DLL named “CAFramework”
and created an assembly named “CodeArchitects.Framework.dll”. Here’s
the pragma that does the trick:
If you omit the assemblyname argument VB Migration Partner attempts to
locate the assembly by matching the assembly name with the filename. For example,
in previous example we could omit the third argument if the .NET file were named
CAFramework.dll.
If the second argument begins with the “@” character, then the copytoprojectfolder
optional argument specifies whether the converted VB.NET project should include
a reference to the specified .NET DLL (if the argument is True) or if VB Migration
Partner should first copy the .NET DLL into the SupportDLLs subfolder and have the
VB.NET project reference this copy. In most cases you can omit this argument and
rely on the default behavior (the DLL isn’t copied into SupportDLLs folder);
you should specify True only if you later want to deploy the VB.NET project on another
computer where the specified .NET DLL isn’t present.
ProjectKind prjkind
Determines the type of the current project. It is useful to specify whether an ActiveX
EXE project should be converted to an EXE or a DLL Visual Basic project. The prjkind
argument is mandatory and can be equal to dll or exe:
SetPragmaPrefix newprefix
This pragma requires VB Migration Partner Enterprise edition
Allows you to select a different prefix for pragmas inserted in VB6 code. The argument
must not include the leading single quote used for remarks:
The argument is considered to be a regular expression, therefore it is necessary
to escape the characters that have a special meaning inside a regex. For example,
if you want to use a double dot as the pragma prefix, you need this pragma:
Using a regex instead of a simple string allows you to specify multiple pragma prefixes.
For example, you can have VB Migration Partner recognize the double dot prefix in
addition to the default prefix:
The prefix doesn’t need to be 2-char long.
You can apply this pragma only by storing it in a *.pragmas file. We suggest that
you use the special file named VBMigrationPartner.pragmas, which you can conveniently
share among all the projects of a complex application. Notice, however, that this
pragma doesn’t affect the pragmas that are stored in *.pragmas files and applies
only to pragmas inserted in VB6 source code files.
This pragma can be useful for two distinct and unrelated reasons:
- You use another source code management tool that relies on remarks that start
with the '## sequence. (For example, only later in the development cycle we realized
that this sequence is used by Innovasys Document! Tool).
- You want to migrate the VB6 code using different sets of pragmas.
As an example of the second approach, let’s suppose that your VB6 code uses
DAO to access an Access database. In the first migration attempt, you generate a
VB.NET application that also uses DAO, but you can then improve the result by generating
ADO.NET code, which surely requires a good amount of PostInclude, PostProcess, and
InsertStatement pragmas. In this case it might make sense to use a different prefix
for the pragmas that add just to support ADO.NET, so that you can quickly switch
from the DAO to the ADO.NET version by just editing one SetPragmaPrefix pragma.
ArrayBounds mode
Specifies how the declaration of arrays with a nonzero lower index must be converted to VB.NET. The
valid values for the mode argument are Unchanged (arrays are migrated
verbatim, the default behavior), ForceZero (the lower index is forced to
be zero), Shift (both the lower and upper indexes are shifted so that the
number of elements in the array doesn’t change), VB6Array (convert
the array into a VB6Array object), or ForceVB6Array (convert the array
into the VB6Array even if the lower index is zero):
Notice that this pragma, like all pragmas that can reference arrays, should be inserted
immediately before the Dim statement that declares the array, rather than before
the ReDim statement that actually creates the array. Pragmas inserted inside the
method where the ReDim statement appears are ignored.
Also notice that this pragma only affects the declaration (DIM) of an array, not
the value of indexes used in code to reference individual array items. For that
purpose you should use a ShiftIndexes pragma.
ArrayRank rank
Specifies the rank of an array. It is useful when VB Migration Partner isn’t
able to determine the correct rank of a multi-dimensional array taken as an argument,
returned by a property or function, or declared at the class level but initialized
elsewhere. Consider the following VB6 example:
Dim arr() As Integer
Function GetArray(initialize As Boolean) As Integer()
If initialize Then ReDim arr(10, 10)
GetArray = arr
End Function
If it weren’t for the ArrayRank pragma, the field and the method would return
a vector instead of a two-dimensional array:
Dim arr(,) As Short
Function GetArray(initialize As Boolean) As Integer(,)
If initialize Then ReDim arr(10, 10)
Return arr.Clone()
End Function
Notice that this pragma must have a nonempty scope.
Also notice that this pragma, like all pragmas that can reference arrays, should
be inserted immediately before the Dim statement that declares the array, rather
than before the ReDim statement that actually creates the array. Pragmas inserted
inside the method where the ReDim statement appears are ignored.
AssumeType type
Informs VB Migration Partner that a given Object, Variant, or Control variable must
be translated as if it were of a specific VB6 type. It is useful to correctly solve
default properties even in late-bound references. For example, consider the following
VB6 code:
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeOf ctrl Is TextBox Then ctrl = ""
Next
If it weren’t for the AssumeType pragma, VB Migration Partner wouldn’t
know how to convert the reference to the default property:
Dim ctrl As Object
For Each ctrl In Me.Controls
If TypeOf ctrl Is VB6TextBox Then ctrl.Text = ""
Next
Notice that this pragma must have a nonempty scope.
AutoDispose mode
This pragma requires VB Migration Partner Enterprise edition
Specifies how fields pointing to disposable objects must be converted. The mode
argument can be No, Yes, or Force. If equal to Yes
or omitted, all Set x = Nothing statements are converted into calls to the SetNothing6
method; if equal to Force, classes that contain disposable field is marked
as IDisposable and all such fields are disposed of in the Dispose method; if equal
to No, disposable objects aren’t handled in any special way (this
setting represents the default behavior and can be useful to override a pragma with
a broader scope). The AutoDispose pragma can be applied to the project, file, class,
or individual field or variable level.
AutoNew boolean
Specifies how auto-instancing object – that is, fields and variables declared
with the As New clause - must be converted. By default, such declarations are converted
verbatim to VB.NET, even though the VB.NET semantics differs from VB6. If the mode
argument is True or omitted, then VB Migration Partner generates code that ensures
that the VB.NET is identical to VB6.
Public Recordset As New ADODB.Recordset
Public Connection As New ADODB.Recordset
The actual code being generated is different for local variables and fields: if
the object is declared as a class-level field, VB Migration Partner converts it
into a property whose Get block contains code that implements the auto-instancing
behavior; if the object is declared as a local variable, all occurrences are wrapper
by AutoNew6 method calls, that ensure that the object is instantiated if necessary.
ChangeType vb6type, nettype
Specifies that all members of a given VB6 type in the pragma’s scope must
be converted to a given .NET type. It is useful to convert Variant variables to
VB6Variant objects and Control variables to System.Windows.Forms.Control variables
(without this pragma, such variables would be migrated as Object variables):
AutoProperty boolean
This pragma requires VB Migration Partner Enterprise edition
Specifies whether public fields should be rendered as properties. If the argument
is True (or omitted) then all public fields are replaced by a read-write property
with same name. For example, the following VB6 code:
Public Name As String
Public Widget As New Widget
is rendered as follows:
Public Property Name() as String
Get
Return Name_InnerField
End Get
Set(ByVal value As String)
Name_InnerField = value
End Set
End Property
Private Name_InnerField As String = ""
Public Property Widget() As Widget
Get
If Widget_InnerField Is Nothing Then Widget_InnerField = New Widget()
Return Widget_InnerField
End Get
Set(ByVal value As Widget)
Widget_InnerField = value
End Set
End Property
Private Widget_InnerField As Widget
Notice that the AutoProperty pragma automatically enforces the auto-instancing (As
New) semantics if possible, regardless of whether the variable is under the scope
of an AutoNew pragma.
ContainsVariantArray bool
This pragma requires VB Migration Partner Enterprise edition
Specifies how arrays contained inside a VB6Variant member should be processed. If
the argument is True (or omitted), the array contained inside all the VB6Variant
variables under the scope of the pragma is considered to be a Variant array (which
has been translated as a VB6Variant array). If False, the contained array is considered
as an array of regular objects.
By default, when VB Migration Partner parses a Variant member that is followed by
an index and a dot, it assumes that the member contains an array of regular objects.
To see why this pragma can be useful, consider the following VB6 code:
Sub Test(ByVal arrObj() As Object, ByVal arrVar() As Variant)
Dim v1 As Variant, v2 As Variant
V1 = arrObj
v2 = arrVar
v1(0).DoSomething
v2(0).DoSomething
End Sub
This is how the code is converted to VB.NET if no other pragma is used:
Sub Test(ByVal arrObj() As Object, ByVal arrVar() As VB6Variant)
Dim v1 As VB6Variant, v2 As VB6Variant
V1 = arrObj
v2 = arrVar
v1(0).DoSomething
v2(0).DoSomething
End Sub
The problem in previous code is that the v2 variable contains an array of VB6Variant
objects, therefore the reference to v2(0) returns a VB6Variant element which does
not expose the DoSomething method. You solve the problem by adding the following
pragma inside the Test method:
which causes the following code to be generated
v2(0).Value.DoSomething
IMPORTANT: This pragma has been
obsoleted in release 1.11.01. In this and all subsequent releases, the indexing
operation on a simple VB6Variant variable always returns a VB6Variant object, therefore
VB Migration Partner always appends the “.Value” suffix when the expression
is followed by a dot. The ContainsVariantArray pragma is therefore useless and is
ignored during the migration process (but no warning is issued).
DeclareImplicitVariables boolean
Specifies whether VB Migration Partner should generate one Dim statement for each
local variable that isn’t declared explicitly. If the argument is True or
omitted, all local variables in the converted VB.NET methods under the pragma’s
scope are declared explicitly.
FixParamArray maxargs
Specifies whether VB Migration Partner should generate a method overload for methods
that take a ParamArray argument and that modify an element of the array argument
inside the method. The method overload uses Optional ByRef parameters instead of
one single ParamArray parameter, and the maxargs value specifies the maximum
number of arguments that you expect. For example, assume that you have the following
VB6 code:
Sub Increment(ParamArray arr() As Variant)
Dim i As Integer
For i = 0 To UBound(arr)
arr(i) = arr(i) + 1
Next
End Sub
Notice that the elements of the arr ParamArray array are modified inside
the method and these changes are propagated back to callers under VB6 but not under
VB.NET. However, the FixParamArray pragma causes the following code to be generated:
Public Sub Increment(Optional ByRef arr0 As Object = Nothing, _
Optional ByRef arr1 As Object = Nothing, _
Optional ByRef arr2 As Object = Nothing)
Dim arr() As Object = GetParamArray6(arr0, arr1, arr2)
Try
Increment(arr)
Finally
SetParamArray6(arr, arr0, arr1, arr2)
End Try
End Sub
Public Sub Increment(ByVal ParamArray arr() As Object)
Dim i As Short
For i = 0 To UBound6(arr)
arr(i) += 1
Next
End Sub
The neat effect is that any call to the Increment method that takes 3 arguments
or fewer will use the first overload, which ensures that changes to any argument
are correctly propagated back to callers even in VB.NET.
If the maxargs argument is 0 or omitted, no overloaded method is generated.
(This behavior is useful to override another FixParamArray pragma with broader scope.)
Values higher than 20 are rounded down to 20.
InferType mode, includeParams
This pragma requires VB Migration Partner Enterprise edition
Specifies whether VB Migration Partner should try to infer the type of the local
variables, class fields, functions, and properties that are under the scope of this
pragma. The mode argument can be one of the following: No if type
inference is disabled; Yes if type inference is enabled only for
members that lacks an explicit As Variant clause and for local variables that are
implicitly declared; Force if type inference is enabled for all
Variant members. The second argument is True if type inference is extended to method
parameters.
VB Migration Partner Enterprise Edition is capable, in most cases, to correctly
deduce a less generic data type for Variant local variables, parameters, class fields,
functions and properties. This applies both to members that were explicitly declared
as Variant and to members that lacked an explicit As clause. To see how this feature
works, consider the following VB6 code:
Private m_Width As Single
Property Get Width ()
Width = m_Width
End Property
Property Let Width (value)
m_Width = value
End Property
Sub Test(x As Integer, frm)
Dim v1 As Variant, v2
v1 = x * 10
v2 = Width + x
Set frm = New frmMain
res = frm.Caption
End Sub
Here’s the migrated VB.NET code:
Private m_Width As Single
Public Property Width() As Single
Get
Return m_Width
End Get
Set(ByVal value As Single)
m_Width = value
End Set
End Property
Public Sub Test(ByRef x As Short, ByRef frm As Form1)
Dim res As String = Nothing
Dim v1 As Integer
Dim v2 As Single
v1 = x * 10
v2 = Width + x
frm = New Form1()
res = frm.Caption
End Sub
Extending the pragma scope to method parameters isn’t always a good idea,
because the current version of VB Migration Partner infers the type of parameters
by looking at assignments inside the method and doesn’t account for
implicit assignments that result from method calls. For this reason, the type inferred
during the migration process might not be correct in some cases.
Important note: Type inference isn’t an exact science and
you should always double-check that the data type inferred by VB Migration Partner
is correct. Even better, we recommend that you use the InferType pragma only during
in early migration attempts and then you later assign a specific type to members
by editing the original VB6 code or by means of the SetType pragma.
LateBoundMethods methodregex, indexregex, varregex
This pragma requires VB Migration Partner Enterprise edition
Specifies which late-bound members should be considered as methods with one or more
ByRef arguments. The first methodregex argument is a regular expression that
specifies which member names are to be considered as the names of methods with ByRef
arguments (use “.+” to indicate “all members”). The second indexregex argument
is a regex that identifies all (0-based) numeric indexes of ByRef parameters of
indicated methods (if omitted, it defaults to “\d+”, which means “all parameters”).
The third parameter is optional and is considered as a regular expression that specifies
which Variant and Object fields and variables the pragma applies to (if omitted,
it defaults to “.+” and therefore all the fields and variables in the pragma’s scope
are affected.
This pragma becomes important in applications that use late-binding quite extensively
and accounts for a subtle but important difference between VB6 and VB.NET. Under
VB6, passing a writable property to a ByRef parameter of a method does not
affect the property (because behind the scenes VB6 is actually passing the return
value from the Property Get block). Vice versa, passing a writable property to a
ByRef parameter does modify the property value on exiting the method
under VB.NET.
Consider the following VB6 code:
Sub Test(ByRef lbl As Label, ByVal txt As TextBox, ByVal wi As Widget, ByVal obj As Object)
Set obj = wi
wi.ModifyValues lbl.Caption, txt.Text
obj.ModifyValues lbl.Caption, txt.Text
End Sub
If the ModifyValue in the Widget class takes one ByRef argument, this is how VB
Migration Partner translates the code to VB.NET:
Sub Test(ByRef lbl As VB6Label, ByVal wi As Widget, ByVal obj As Object)
Set obj = wi
wi.ModifyValue(ByVal6(lbl.Caption), ByVal6(txt.Text))
obj.ModifyValue(lbl.Caption, txt.Text)
End Sub
The ModifyValue method can modify the lbl.Caption and txt.Text writable
properties under VB. NET and that this modification would break functional equivalence
with the original VB6 code. VB Migration Partner knows how to work around this difference
and correctly wraps the two property references inside a ByVal6 method when calling
the wi.ModifyValue method.
VB Migration Partner can carry out this correctly because the ModifyValue
is referenced using early-binding (i.e. the wi member has a definite type)
and it is possible to detect that the lbl.Caption and txt.Text
values are being passed to a ByRef parameter. Conversely, the obj.ModifyValue
call uses late binding and VB Migration Partner can’t decide whether the called
method takes one or more ByRef parameters.
In this scenario you can use the LateBoundProperties pragma to let VB Migration
Partner know which late-bound members are to be considered as methods that take
one or more ByRef parameters. Here’s how the pragma might be used in this
specific example:
Sub Test(ByRef lbl As Label, ByVal txt As TextBox, ByVal wi As Widget, ByVal obj As Object)
Set obj = wi
wi.ModifyValues lbl.Caption, txt.Text
obj.ModifyValues lbl.Caption, txt.Text
End Sub
which produces the following code:
Sub Test(ByRef lbl As VB6Label, ByVal wi As Widget, ByVal obj As Object)
Set obj = wi
wi.ModifyValue(ByVal6(lbl.Caption), ByVal6(txt.Text))
obj.ModifyValue(ByVal6(lbl.Caption), ByVal6(txt.Text))
End Sub
Consider that the pragma’s first argument is actually a regular expression,
which allows you to specify multiple methods in just one pragma. (This is necessary
because you can associate only one LateBoundMethods pragma to a given variable.)
Therefore you might write something like
or just assume that all exposed members are to be considered as methods that can
modify their arguments:
The second optional argument of the LateBoundMethods pragma is a regular expression
that is applied to the 0-based numeric index of the argument being analyzed. If
omitted, this regex defaults to “\d+”, therefore all parameters are
considered to be defined with ByRef. For example, if you knew that only the second
argument of the Widget.ModifyValues method is defined with ByRef, you can avoid
useless ByVal6 insertions using this pragma:
If just the 2nd and 3rd parameters are defined with ByRef
you need this pragma:
and so on.
The third argument of the LateBoundMethods pragma allows you to apply the pragma
to multiple variables and fields under the pragma’s scope, without having
to specify a different pragma for each one of them. For example, consider the following
VB6 code:
Sub Test(ByVal obj As Object, ByVal obj2 As Object, ByVal obj3 As Object)
Set obj = New Widget
Set obj2 = New Widget
Set obj3 = New Person
obj.ModifyValues lbl.Caption, txt.Text
obj2.ModifyValues lbl.Caption, txt.Text
obj3.ModifyValues lbl.Caption, txt.Text
End Sub
If both the Widget and Person classes expose a ModifyValues method that takes ByRef
arguments, you might use the following pragma to affect all of them:
Sub Test(ByVal obj As Object, ByVal obj2 As Object, ByVal obj3 As Object)
Set obj = New Widget
Set obj2 = New Widget
Set obj3 = New Person
obj.ModifyValues lbl.Caption, txt.Text
obj2.ModifyValues lbl.Caption, txt.Text
obj3.ModifyValues lbl.Caption, txt.Text
End Sub
However, if you don’t want to apply the pragma to obj3, you would
be forced to specify a distinct pragma for obj and obj2. The pragma’s
third argument allows you to write more concise code:
Notice that VB Migration Partner applies the two regular expressions using the Regex.IsMatch
method, therefore the following pragma wouldn’t achieve the intended effect:
because it would also match the obj3 member name.
If the VB6 code consistently uses a naming convention for its late-bound members,
the pragma’s second argument can be quite useful. For example, if all the
Variant and Object variables that are meant to store a reference to an ADODB.Connection
have a leading “conn” in their name, you might use the following pragma:
to indicate that the second argument (i.e. the RecordsAffected argument)
of the Execute method can be modified on return from the call.
Finally, you can also change VB Migration Partner’s default behavior by considering
all late-bound names as references to methods with ByRef arguments:
or more simply with
Notice that a LateBoundMethods pragma with a narrow scope shadows all the LateBoundMethods
pragmas at a broader scope. For example, the above project-level pragma doesn’t
apply to methods where another LateBoundMethods pragma is defined.
LateBoundProperties propregex, varregex
This pragma requires VB Migration Partner Enterprise edition
Specifies which late-bound members should be considered as writable properties.
The first propregex argument is a regular expression that specifies which
member names are to be considered as the names of writable properties (use “.+”
to indicate “all members”). The second parameter is optional and is
considered as a regular expression that specifies which Variant and Object fields
and variables the pragma applies to (if omitted, it defaults to “.+”
and therefore all the fields and variables in the pragma’s scope are affected.
This pragma becomes important in applications that use late-binding quite extensively
and accounts for a subtle but important difference between VB6 and VB.NET. Under
VB6, passing a writable property to a ByRef parameter of a method does not
affect the property (because behind the scenes VB6 is actually passing the return
value from the Property Get block). Vice versa, passing a writable property to a
ByRef parameter does modify the property value on exiting
the method under VB.NET.
Consider the following VB6 code:
Sub Test(ByVal lbl As Label, ByVal obj As Object)
DoSomething lbl.Caption, obj.Caption
End Sub
Sub DoSomething(ByRef str As String)
str = UCase(str): str2 = UCase(str2)
End Sub
If no pragma is added, this is how VB Migration Partner translates the code to VB.NET:
Sub Test(ByVal lbl As VB6Label, ByVal obj As Object)
DoSomething(ByVal6(lbl.Caption), obj.Caption)
End Sub
Sub DoSomething(ByRef str As String, ByRef str2 As String)
str = UCase(str): str2 = UCase(str2)
End Sub
As you see, VB Migration Partner knows how to work around this difference and correctly
wraps the lbl.Caption property reference inside a ByVal6 method when calling
the method. This is possible because the property is referenced using early-binding
(i.e. the lbl member has a definite type) VB Migration Partner can detect
that a writable property is being passed. Conversely, the obj.Caption member uses
late binding and VB Migration Partner can’t decide whether Caption is a reference
to a writable property and omits the necessary ByVal6 code.
In this scenario you can use the LateBoundProperties pragma to let VB Migration
Partner know which late-bound members are writable properties. In this specific
case you might use this pragma
Sub Test(ByVal lbl As Label, ByVal obj As Object)
DoSomething lbl.Caption, obj.Caption
End Sub
However, consider that the pragma’s first argument is actually a regular expression,
which allows you to specify multiple properties in just one pragma. (This is necessary
because you can associate only one LateBoundProperties pragma to a given variable.)
Therefore you might write something like
or just assume that all exposed members are to be considered as writable properties:
The second optional argument of the LateBoundProperties pragma allows you to apply
the pragma to multiple members under the pragma’s scope, without having to
specify a different pragma for each one of them. For example, consider the following
VB6 code:
Sub Test(ByVal obj As Object, ByVal obj2 As Object, ByVal obj3 As Object)
DoSomething obj.Caption, obj2.Caption, obj3.Caption
End Sub
If you can assume that all three parameters represent a control you might use the
following pragma to affect all of them:
Sub Test(ByVal obj As Object, ByVal obj2 As Object, ByVal obj3 As Object)
DoSomething obj.Caption, obj2.Caption, obj3.Caption
End Sub
However, if you don’t want to apply the pragma to obj3, you would
be forced to specify a distinct pragma for obj and obj2. The pragma’s
second argument allows you to write more concise code:
Notice that VB Migration Partner applies the two regular expressions using the Regex.IsMatch
method, therefore the following pragma wouldn’t achieve the intended effect:
because it would also match the
obj3 member name.
If the VB6 code consistently uses a naming convention for its late-bound members,
the pragma’s second argument can be quite useful. For example, if all the
Variant and Object variables that are meant to store a reference to an ADODB.Connection
have a leading “conn” in their name, you might use the following pragma:
Finally, you can also change VB Migration Partner’s default behavior by having
all references to all late-bound members wrapped in ByVal6 method, as follows:
or more simply with
Notice that a LateBoundProperties pragma with a narrow scope shadows all the LateBoundProperties
pragmas at a broader scope. For example, the above project-level pragma doesn’t
apply to methods where another LateBoundProperties pragma is defined.
LateBoundVariantMembers propregex, varregex, canReturnEmpty
This pragma requires VB Migration Partner Enterprise edition
Specifies which late-bound members should be considered as properties or methods
that return a Variant value. The first propregex argument is a regular
expression that specifies which member late-bound names can return a Variant value
(use “.+” to indicate “all members”). The second parameter
is optional and is considered as a regular expression that specifies which Variant
and Object fields and variables the pragma applies to (if omitted, it defaults to
“.+” and therefore all the fields and variables in the pragma’s
scope are affected). The third Boolean parameter is also optional and should be
set to True if the Variant being returned can be the special Empty value.
This pragma can be necessary to prevent a few runtime exceptions when working with
VB6Variant values and therefore is always used together with a ChangeType pragma
like this one:
If the LateBoundVariantMembers pragma is used, all methods and
properties (within the scope of the pragma) invoked in late-bound mode – that
is, through an Object or VB6Variant variable – are assumed to return a VB6Variant
value. In practice, this pragma causes the invocation to be wrapper inside a
CVar6 method in the following cases:
- The member appears to the left or right of a comparison operator (e.g. = or <> operators)
- The member appears to the left or right of a math operator, and the other operand isn’t a VB6Variant value
- The return value from the member is being assigned to an array or an object variable
- The return value from the member is being assigned to a scalar value (only if pragma’s 3rd argument is True)
MergeInitialization mode
This pragma requires VB Migration Partner Enterprise edition
Specifies whether a specific local variable (or all local variables in a method)
must be merged with the first statement that assigns it a value. By default, VB
Migration Partner merges a variable declaration with its first assignments only
if the value being assigned is constant and if the variable isn’t used in
any statement after the declaration and before the assignment. You can use this
pragma to inform VB Migration Partner that it is safe to do the merge even if the
value being assigned isn’t constant. For example, consider this VB6 code:
Sub Test(value As Integer)
Dim x As Integer, y As Integer
x = value * 2
y = x * value * 3
End Sub
The values being assigned aren’t constant, therefore by default VB Migration
Partner wouldn’t attempt to merge the declaration and the assignment statements.
Thanks to the MergeInitialization pragma, the code generator produces the following
code:
Sub Test(value As Short)
Dim x As Short = value * 2
Dim y As Short = x * value * 3
End Sub
Other possible values for this pragma are No (always disable the
merging) or Yes (apply the merging if it is safe to do so). The
Yes value represents the default behavior, but this setting can be necessary to
override the effect of another MergeInitialization pragma with a broader scope:
Note: in a method that contains one or more Gosub statements that
are converted to separate methods because of a ConvertGosubs pragma, this pragma
is ignored and the variable initialization merging feature is disabled.
SetName membername
Specifies whether the current project, class, method, property or variable must
have a different name in the converted VB.NET application. It can be useful to avoid
name clashes with reserved VB.NET keywords or names of .NET Framework classes and
methods. Consider the following VB6 code:
Public Id As String
Sub AddHandler()
End Sub
Sub Test()
Dim c As New Console
c.Id = "abc"
c.AddHandler
End Sub
Here’s how the code inside the Test method is converted to VB.NET:
Sub Test()
Dim c As New ConsoleNET
c.Identifier = "abc"
c.AddEventHandler()
End Sub
ShiftIndexes applytovariables, delta1 [, delta2, delta3]
This pragma requires VB Migration Partner Enterprise edition
Specifies whether the indexes of the element of an array should be adjusted by a
given value. The applytovariables argument is False if only constant indexes
should be adjusted, True if all indexes should be adjusted; delta1 is the
value that must be subtracted from the first index; delta2 and delta3
are the values that must be subtracted from the second and third index, respectively.
This pragma is typically used together with the ArrayBounds pragma. Consider the
following VB6 code:
Sub Test()
Dim primes(1 To 10) As Integer
primes(1) = 1: primes(2) = 2: primes(3) = 3: primes(4) = 5: primes(5) = 7
Dim powers(1 To 10) As Double
powers(1) = 1
Dim i As Integer
For i = LBounds(powers) + 1 To UBound(powers)
powers(i) = powers(i – 1) * 2
Next
End Sub
The ShiftIndexes pragmas ensure that the array elements whose index is constants
are scaled by 1 when this code is converted to VB.NET:
Sub Test()
Dim primes(9) As Short
primes(0) = 1: primes(1) = 2: primes(2) = 3: primes(3) = 5: primes(4) = 7
Dim powers(9) As Double
powers(0) = 1
Dim i As Short
For i = LBounds6(powers) + 1 To UBound6(powers)
powers(i) = powers(i – 1) * 2
Next
End Sub
In most cases, the first argument of the ShiftIndexes pragma is False, which prevents
this pragma from affecting array elements whose index is a variable or an expressions,
as it usually happens inside a loop. However, this isn’t a fixed rule and
the value for the applytovariables argument actually depends on how the
loop is defined. For example, consider a variations of the above code:
Dim powers(1 To 10) As Double
powers(1) = 1
Dim i As Integer
For i = 2 To 10
powers(i) = powers(i – 1) * 2
Next
In this case the lower and upper bounds of the loop are constants and aren’t
expressed in terms of LBound and UBound functions, therefore you need to pass True
in the first argument of the ShiftIndexes pragma to adjust the indexes inside the
loop. This is the generated VB.NET code:
Dim powers(9) As Double
powers(0) = 1
Dim i As Short
For i = 2 To 10
powers(i - 1) = powers(i – 1 - 1) * 2
Next
When dealing with a multi-dimensional array you need to pass more than two elements
to the ShiftIndexes pragma, as in the following code:
Dim mat(1 To 10, 2 To 20) As Double
mat(1, 2) = 1: mat(2, 3) = 2
which is converted to VB.NET as follows:
Dim mat(9, 18) As Double
mat(0, 0) = 1: mat(1, 2) = 2
Finally, notice that the delta values don’t have to be constants, as in this
example:
Sub Test(arr() As Double, firstEl As Integer, numEls As Integer)
ReDim arr(firstEl To lastEl) As Double
arr(firstEl) = 1
End Sub
which is converted as follows:
Sub Test(ByRef arr() As Double, ByRef firstEl As Short, ByRef numEls As Short)
ReDim arr(lastEl – (firstEl)) As Double
arr(firstEl - firstEl) = 1
End Sub
Notice that this pragma, like all pragmas that can reference arrays, should be inserted
immediately before the Dim statement that declares the array, rather than before
the ReDim statement that actually creates the array. Pragmas inserted inside the
method where the ReDim statement appears are ignored.
SetStringSize nnn
Specifies that a fixed-length string must be converted as a VB6FixedString_NNN
type instead of the VB6FixedString type. For example, the following VB6 code:
Dim id As String * 20, name * As String * 128
is converted to VB.NET as follows:
Dim id As New VB6FixedString(20)
Dim id As New VB6FixedString_128
where the VB6FixedString_128 class is defined in the VisualBasic6.Support.vb file
under the My Project folder.
SetType nettype
Specifies that the specified variable, field, property or method must be rendered
with a different .NET type. It is useful to specify a type other than Object for
Variant and Control variables. For example, the following VB6 code:
Private m_Name As Variant
Property Get Name() As Variant
Name = m_Name
End Property
is translated to VB.NET as follows:
Private m_Name As String
Public ReadOnly Property Name() As String
Get
Return m_Name
End Get
End Property
Notice that this pragma must have a nonempty scope.
ThreadSafe Boolean
This pragma requires VB Migration Partner Enterprise edition
Specifies whether variables defined in modules must be decorated with the ThreadStatic
attribute. This attribute is only useful when migrating VB6 DLLs that are meant
to be used by free-threaded .NET clients, for example ASP.NET pages or COM+ server
components. It serves to reduce the gap between the Single-Thread Apartment (STA)
model used by VB6 and the free-thread model used by .NET:
Public UserName As String
If previous code is inside a BAS module, then VB Migration Partner generates what
follows:
<ThreadStatic()> _
Public UserName As String
The ThreadStatic attribute forces the VB.NET compiler to allocate the UserName variable
in the Thread-Local Storage (TLS) area, so that each thread sees and works with
a different instance of the variable. This approach makes free-threading more akin
to the STA model and avoid many subtle runtime errors due to concurrency and race
conditions between threads.
UseByVal mode
This pragma requires VB Migration Partner Enterprise edition
Specifies how to convert by-reference parameters that might be rendered using by-value
semantics. The mode argument can be Yes (the ByVal keyword is
used for the parameter unless an explicit ByRef keyword is present), Force
(the ByVal keyword is used for the parameter, regardless of whether an explicit
ByRef keyword is present), No (the parameter is translated as is):
If the parameter is omitted, the Yes value is assumed.
UseSystemString boolean
Specifies whether fixed-length strings inside inside Type…End Type blocks
must be converted to VB.NET. If the argument is True or omitted, fixed-length strings
inside the pragma’s scope are converted as properties that take or return
System.String values.
ConvertGosubs boolean, optimize
This pragma requires VB Migration Partner Enterprise edition
Specifies whether VB Migration Partner should attempt to convert old-styled Gosubs
into calls to separate methods. The first boolean argument is True (or omitted)
to enable this conversion; the second Boolean argument is True if you want to optimize
the generated code so that parameters of the separate method are declared with ByVal
if possible. This pragma can have project-, file-, or method-level scope. For example,
consider the following VB6 code:
Function GetValue(x As Integer) As Integer
On Error Resume Next
Dim s As String, name As String
s = "ABC"
name = "Code Architects"
GoSub BuildResult
Exit Function
BuildResult:
GetValue = x + Len(s) + Len(name)
Return
End Function
VB Migration Partner detects that the code that begins at the BuildResult label
(a.k.a. the target label) can be safely refactored to a separate method, that receives
four arguments. The result of the conversion is therefore:
Public Function GetValue(ByRef x As Short) As Short
Dim s As String
Dim name As String
On Error Resume Next
s = "ABC"
name = "Code Architects"
Gosub_GetValue_BuildResult(x, GetValue, s, name)
Exit Function
End Function
Private Sub Gosub_GetValue_BuildResult(ByRef x As Short, ByRef GetValue As Short, _
ByRef s As String, ByRef name As String)
On Error Resume Next
GetValue = x + Len6(s) + Len6(name)
End Sub
Notice that the external method contains an On Error Resume Next statement, because
the original GetValue method also contains this statement.
All arguments to the new Gosub_GetValue_BuildResult method are passed by
reference, so that the caller can receive any value that has been modified inside
the method (as is the case with the GetValue parameter in previous example.)
You can have VB Migration Partner optimize this passing mechanism and use ByVal
if possible by passing True as the second argument to the ConvertGosubs pragma:
If this optimization is used in the above code, the separate method is rendered
as follows:
Private Sub Gosub_GetValue_BuildResult(ByVal x As Short, ByRef GetValue As Short, _
ByVal s As String, ByVal name As String)
On Error Resume Next
GetValue = x + Len6(s) + Len6(name)
End Sub
If you don’t like the name that VB Migration Partner assigns to the automatically-generated
method, you can easily change it by means of a PostProcess pragma:
It is important to keep in mind that the conversion of a Gosub block of code into
a separate method isn’t always possible. More precisely, VB Migration Partner
can perform this conversions only if all the following conditions are met:
- The method doesn't contain any Resume statement. (On Error Resume Next is OK, though).
- The target label isn't located inside a If, Select, For, Do, or Loop block.
- The target label isn't referenced by a Goto, On Goto/Gosub, or On Error statement.
- The target label must be preceded by a Goto, Return, End, Or Exit Sub/Function/Property
statement.
- The code block must terminate with an inconditional Return.
(Blocks that terminate with End Sub/Function/Property or Exit Sub/Function/Property statements aren't converted.)
- The block of code between the target label and the closing Return/End statement
doesn't contain another label.
If a method contains one or more labels that can’t be converted to a separate
method, VB Migration Partner still manages to convert the remaining labels. In general,
a label can be converted to a separate method if it neither references nor is referenced
by a label that can’t be converted (for example, a label that is defined inside
an If block or a label that doesn’t end with an unconditional Return statement.)
Note: in a method that contains one or more Gosub statements that
are converted to separate methods, the variable initialization merging feature is
disabled.
DefaultMemberSupport boolean
Specifies whether VB Migration Partner must wrap references to default members inside
calls to the special GetDefaultMember6 and SetDefaultMember6 methods defined in
the language support library:
FixRemarks boolean
This pragma requires VB Migration Partner Enterprise edition
Specifies how VB Migration Partner must convert VB6 remarks that start with three
consecutive apostrophes. By default they are prefixed by an additional apostrophe+space,
so that the VB.NET compiler doesn’t mistakenly interpret them as XML remarks.
You can use False for the argument to disable such automatic fix, which can be useful
if you decide to insert VB.NET XML remarks right in the VB6 code:
LogicalOps boolean
This pragma requires VB Migration Partner Enterprise edition
Specifies whether And and Or VB6 keywords must be translated to AndAlso and OrElse
VB.NET keywords. For example, the following code:
Sub Test(ByVal x As Integer)
If x < 0 And x > 100 Then Err.Raise 9
End Sub
The pragma can have project, class, and method scope, and can issued multiple times
inside the same method, to selectively enable and disable this feature. For example,
this VB6 code:
If x > 0 Or (x = 0 And y < 0) Then …
If x1 > 0 Or (x1 = 0 And y1 < 0) Then …
translates to:
If x > 0 OrElse (x = 0 AndAlso y < 0) Then …
If x1 > 0 Or (x1 = 0 And y1 < 0) Then …
MergeIfs boolean, includeParens
This pragma requires VB Migration Partner Enterprise edition
Specifies whether two or more nested Ifs are automatically merged into a single
statement by means of an AndAlso operator. This pragma can have project, class,
and method scope. The first argument can be True (default if omitted) or False,
where the latter value can be used to override another pragma with broader scope.
The includeParens optional argument is True (default if omitted) if you
want to enclose individual expressions within parenthesis, or False to drop these
parenthesis.
For example, consider the following code
Sub Test(ByVal obj As Object, ByVal obj2 As Object)
If Not obj Is Nothing Then
If obj.Text = "" Then Debug.Print "Empty Text"
End If
If Not obj Is Nothing Then
If Not obj2 Is Nothing Then
If obj.Text = obj2.Text Then Debug.Print "Same text"
End If
End If
End Sub
This is how VB Migration Partner translates it to VB.NET
Sub Test(ByVal obj As Object, ByVal obj2 As Object)
If (Not obj Is Nothing) AndAlso (obj.Text = "") Then
Debug.WriteLine("Empty Text")
End If
If (Not obj Is Nothing) AndAlso (Not obj2 Is Nothing) AndAlso (obj.Text = obj2.Text) Then
Debug.WriteLine("Same text")
End If
End Sub
You can further simplify the expression by dropping the parenthesis around each
subexpressions, by using the following pragma:
Notice that this optimization is disabled if there are one or more special pragmas
between the two IF statements, including InsertStatement, ReplaceStatement, PreInclude
and PostInclude.
NullSupport boolean
Specifies whether VB Migration Partner must generate code that provides better support
for null propagation in expressions. For example, consider the following VB6 code:
Sub Test(name As Variant, city As Variant)
name = UCase(name) + Trim(city)
End Sub
and its VB.NET translation
Sub Test(ByRef name As Object, ByRef city As Object)
name = UCase6(name) + Trim6(city)
End Sub
Methods affected by this pragma are: Chr, CurDir, Environ, Error, Hex, LCase, LTrim,
Mid, Oct, Right, RTrim, Space, and UCase. The corresponding method in the language
support library has same name plus a "6" suffix.
PreInclude includefile
This pragma requires VB Migration Partner Enterprise edition
Includes a text file before the parsing process begins. The argument is the path
to the text file that contains the text to be included. (It can be an absolute path
or a path relative to the folder that contains the .vbp project file.). The argument
never needs to be included in double quotes:
If the includefile argument points to a non-existing file, no text is included
and no migration warning is generated. The PreInclude pragma supports recursion,
in the sense that the file being included can contain additional PreInclude pragmas,
up to any nesting level. VB Migration Partner doesn’t allow circular references
among include files.
Keep in mind that you typically can’t use this pragma to include a standard
CLS or BAS file, because such VB6 files contains hidden text and attributes that
would be included in the wrong position and might deliver unexpected results or
even crash VB Migration Partner. You use this pragma at your own risk.
A good use for this pragma is as a simple way for multiple project to share the
same set of project-level pragmas. For example, let’s assume that you have
to migrate ten VB6 projects that require the same set of PostProcess pragmas. Instead
of copying the pragma text in each and every project, you can gather them in a text
file and reference the text from inside any source file in each project:
Notice, however, that in this specific case, the pragma.txt file can’t contain
the special pragmas that must be parsed before the project itself and that are necessarily
to be stored in the VBMigrationPartner.pragmas file. However, quite conveniently
PreInclude pragmas are honored even inside *.pragmas files, therefore each folder
might contain a VBMigrationPartner.pragmas file that contains only one line containing
the PreInclude pragma pointing to the text file that contains the actual pragmas
that are shared among multiple projects.
PreProcess searchpattern, replacepattern, ignorecase, applytohiddencode, regionpattern
Applies a replace regular expression to the VB6 code before it is parsed. The first
argument is the search regex pattern string. The second argument is the replace
regex pattern and can reference match groups defined in the search pattern; it abides
to the same syntax rules as the Regex.Replace method but it also recognizes character
sequences such as \n (newline), \r (carriage return) and \t (tab). Backslash characters
in the replace regex must be doubled (as in \\). The third argument is a Boolean
value that specifies whether searches are case insensitive (if omitted, it defaults
to True). The fourth argument is True if this pragma applies also to the .vbp file
and to the hidden portion of an .frm or .ctl file, False (or omitted) if it applies
only to the VB6 code that you see inside the code editor. The fifth argument is
an optional regex pattern that can be used to precisely indicate the code regions
to which the search pattern must be applied.
For example, the following pragma pre-processes the VB6 code and converts all OLE_COLOR
variables into plain Long variables:
The following pragma renames a button named “AddHandler” into “btnAddHandler”,
to avoid the problem caused by AddHandler being a reserved VB.NET keyword. In this
case it is necessary to apply the pragma to the hidden portion of the file and to
account for event names, where the control’s name is followed by an underscore
The following example uses the optional regionpattern argument to restrict
the action of the PreProcess pragma to Sub methods only:
Notice that the last argument uses the .+? pattern to ensure that the search region
doesn’t extend to more than one method at a time.
You can apply this pragma at the project-level only by storing it in a *.pragmas
file – for example, in the Widgets.vbp.pragmas file for all the files in the
Widgets.vbp project. An important note: this pragma can’t have a project:
prefix: if the pragma appears in a source file it is implicitly scoped at the file
level; if it appears in a *.pragmas file, it is implicitly scoped at the project
level.
PostInclude includefile
This pragma requires VB Migration Partner Enterprise edition
Includes a text file after the conversion process has been completed. The argument
is the path to the text file that contains the text to be included. (It can be an
absolute path or a path relative to the folder that contains the .vbp project file.).
The argument never needs to be included in double quotes:
If the includefile argument points to a non-existing file, no text is included
and no migration warning is generated. The PostInclude pragma supports recursion,
in the sense that the file being included can contain additional PostInclude pragmas,
up to any nesting level. VB Migration Partner doesn’t allow circular references
among include files.
A good use for this pragma is to add one or more methods or classes to the resulting
VB.NET code.
PostProcess searchpattern, replacepattern, ignorecase, applytohiddenfiles, regionpattern
Applies a replace regular expression to the VB.NET code generated by the migration
process. The first argument is the search regex pattern string. The second argument
is the replace regex pattern and can reference match groups defined in the search
pattern; it abides to the same syntax rules as the Regex.Replace method but it also
recognizes character sequences such as \n (newline), \r (carriage return) and \t
(tab). Backslash characters in the replace regex must be doubled (as in \\). The
third argument is a Boolean value that specifies whether searches are case insensitive
(if omitted, it defaults to True). The fourth argument specifies whether the PostProcess
pragma applies only to “hidden” files such as AssemblyInfo.vb and *.vbproj
files (if omitted, it defaults to False and the pragma applies only to standard
*.vb files, including *.Designer.vb files). The fifth argument is an optional regex
pattern that can be used to precisely indicate the code regions to which the search
pattern must be applied.
For example, the following pragma changes the base form for the converted application:
The search pattern can include match groups and you can reference these search groups
in the replacement pattern. For example, the following pragma moves the declaration
of the controlling variable into a For Each loop, if the variable is defined immediately
before the loop:
The following example is similar to previous one, except it uses the optional regionpattern
argument to restrict the action of the PostProcess pragma only to Function methods
named GetArray and GetString:
Notice that the last argument uses the .+? pattern to ensure that the search region
doesn’t extend to more than one function at a time.
PreservePropertyAssignmentKind mode
This pragma requires VB Migration Partner Enterprise edition
Specifies whether VB Migration Partner must take additional cure when converting
custom properties. If Yes (or omitted) the pragma applies only to properties
whose definition contains both a Property Let and a Property Set; if Force
it applies to all properties that have a Property Let block, even if the Property
Set block is missing. In all cases, the pragma applies only to properties whose
Let block specifies a non-scalar data type.
To understand when this pragma can be necessary, let’s consider the following
VB6 code:
Private m_MyData As Variant
Property Get MyData() As Variant
If Not IsObject(m_MyData) Then
MyData = m_MyData
Else
Set MyData = m_MyData
End If
End Property
Property Let MyData(ByVal newValue As Variant)
m_MyData = newValue
ProcessDataValue newValue
End Property
Property Set MyData(ByVal newValue As Variant)
Set m_MyData = newValue
End Property
Sub Main()
Dim rs As New ADODB.Recordset, par As New ADODB.Parameter
MyData = par
Set MyData = par
MyData = rs
Set MyData = rs
End Sub
This is how VB Migration Partner usually converts the above code:
Private m_MyData As Object
Property MyData() As Object
Get
Return m_MyData
End Get
Set(ByVal newValue As Object)
If Not IsObject6(newValue) Then
m_MyData = newValue
ProcessDataValue(newValue)
Else
m_MyData = newValue
End If
End Set
End Property
Sub Main()
Dim rs As New ADODB.Recordset
MyData = par.Value
MyData = par
MyData = rs.Fields
MyData = rs
End Sub
Notice that VB Migration Partner expands par into par.Value and rs
into rs.Fields when the assignment to the MyData property
lacks the Set keyword. While the two cases seem similar, they aren’t. The
key different is that the ADODB.Parameter’s default property (Value) is a
scalar value (a string, a number, a date, etc.) whereas the ADODB.Recordset’s
default property (Fields) is an object.
When par.Value is assigned to the MyData property, the following statement
If Not IsObject6(newValue) Then
recognizes that it’s a scalar and executes the code block that was originally
in the Property Let procedure (and therefore the ProcessDataValue method
is correctly invoked). However, when rs.Fields is assigned to the MyData
property, the test in the If statement finds that it’s not a scalar and mistakenly
executes the code block that was originally in the Property Set procedure. As a
result, the ProcessDataValue method isn’t invoked as it should have
been.
(You can also omit the argument, because Yes is the default). You can solve this
problem by applying the PreservePropertyAssignmentKind pragma to the MyData property,
as follows:
In this case VB Migration Partner generates the following VB.NET code:
Private m_MyData As Object
Property MyData(ByVal Optional _assignmentKind As PropertyAssignmentKind _
= PropertyAssignmentKind.Let) As Object
Get
Return m_MyData
End Get
Set(ByVal newValue As Object)
If _assignmentMode = PropertyAssignmentKind.Let Then
m_MyData = newValue
ProcessDataValue(newValue)
Else
m_MyData = newValue
End If
End Set
End Property
Sub Main()
Dim rs As New ADODB.Recordset
MyData = par
MyData(PropertyAssignmentKind.Set) = par
MyData = rs
MyData(PropertyAssignmentKind.Set) = rs
End Sub
In this new version the task of determining whether the original assignment was
performed by means of a Let or a Set is carried out by means of the _assignmentMode
parameter. Being optional, the parameter is omitted when assigning using a “let”
and is used only in “set” assignments, which helps generating less cluttered
code.
Notice that when this pragma is used, the default property isn’t expanded
any longer and the newValue parameter receives the actual object being
assigned, not its default property. This is exactly what the happens in VB6.
By default, the pragma applies only to properties that have both a Property Let
and a Property Set pragma. However, if you use Force as an argument, the
pragma applies also to properties that have only the Property Let block (provided
that the parameter for such block is Variant or a non-scalar type). In this case
the PropertyAssignmentKind argument is generated but never used, and the pragma
only has the effect of preventing VB Migration Partner from generating.
SetOption optionname, boolean
Specifies a code generation option, depending on the argument passed in the first
argument. Supported options are:
VariantContainsArray: VB Migration Partner assumes that VB6Variant
variables under the scope of this pragma may contain an array; as a result, when
passing a VB6Variant variable to a ByVal VB6Variant parameter, the variable is wrapped
in a CVar6 method, to ensure that the inner array is correctly cloned.
FixedStringsAsStructures: VB Migration Partner generates one member
named "VB6FixedString_NNN" (where NNN is a number) for each fixed-length
string that is used inside an array. By default such members are generated as classes,
but if this parameter is True or omitted then the member is rendered as a strictire.
(This option has been introduced in version 1.23 to preserve compatibility with
older versions, which rendered those members as classes.) This option is always
applied to the entire project, regardless of the specified scope.
RemarkMethodBody: VB Migration Partner remarks out all the statements
inside all properties and methods under the scope of this pragma, so that you can
correctly resolve property/method references without having to fix individual statements
that cause a compilation error. This pragma is especially useful to incrementally
migrate large VB6 projects, one file at a time. You can specify this pragma
at the project, file, and method level. (If applied at the variable level, this
pragma is ignored.)
For example, the following pragmas force VB Migration Partner to generate fixed-length
strings as structures and to remark all statements in all methods in the current
project. Notice that you can omit the second argument if it is True:
ExcludeMethodBody: VB Migration Partner excludes all statements
inside methods and property procedures when parting the VB6 source code, but not
method and property signatures (so that it can correctly resolve all references).
This pragma is especially useful to incrementally migrate very large VB6
projects, one file at a time, to speed up the migration process of large files,
and to avoid out-of-memory errors during the migration process. You can specify
this pragma at the project, file, and method level. (If applied at the variable
level, this pragma is ignored.)
For example, the following pragmas force VB Migration Partner to exclude statements
in all methods in the current project. Notice that you can omit the second argument
if it is True:
When applied at the project level, the SetOption ExcludeMethodBody pragma must be
included in a *.pragmas file.
UseTryCatch boolean, maxExecLines
This pragma requires VB Migration Partner Enterprise edition
Specifies whether VB Migration Partner should attempt to convert error-handling
code inside a method by means of structured error handling based on the Try…Catch
block. The first optional argument can be True (or omitted) if you want to use structured
exception handling, or False to suppress this feature (can be useful to override
a UseTryCatch pragma with a broader scope. The second optional argument maxExecLines
is the max number of executable statements in a method that contains an On Error
Resume Next statement (default value is 2).
Here’s an example of this pragma:
Sub Test()
On Error Goto ErrorHandler
ErrorHandler:
End Sub
This is how the code is translated to VB.NET:
Sub Test()
Try
Catch _ex As Exception
End Try
End Sub
The Try…Catch block can be inserted only if the following conditions are
all true:
- The method contains only a single On Error GoTo <label> method.
- The On Error GoTo <label> statement doesn’t appear inside a conditional
block such as If, For, Select Case, and isn’t preceded by a GoTo statement.
- The method doesn’t contain GoSub, Resume, or Resume Next statements. (Resume
<label> statements are acceptable, though)
- There is no Goto statement in the method body that points to a label that is defined
in the error handler. (Notice that it is ok if a GoTo in the error handler points
to a label defined in the method body.)
- If the method contains one or more On Error Goto 0 statements, such statements must
immediately precede a statement that causes exiting from the current method, e.g.
Exit Sub or End Function.
- If the current method is a Property Let procedure, there must not be a Property
Set procedure for the same property. Likewise, If the current method is a Property
Set procedure, there must not be a Property Let procedure for the same property.
For example, the following VB6 code:
Sub Test()
On Error Goto ErrorHandler
If x > 0 Then GoTo ErrorHandler2
ErrorHandler:
ErrorHandler2:
End Sub
can't be converted to VB.NET using a Try-Catch block because a GoTo statement in
the method body points to a label that is defined in the error handler.
By default, VB Migration Partner inserts a Try-Catch also if the method contains
the On Error Resume Next statement plus another executable statement. For example,
the following VB6 code:
Function Reciprocal(ByVal x As Double) As Double
On Error Resume Next
Reciprocal = 1 / x
End Function
contains only two executable statements (including On Error Resume Next) and is
converted to:
Function Reciprocal(ByVal x As Double) As Double
Try
Return 1 / x
Catch
End Try
End Function
Methods with three or more executable statements can be converted using Try Catch
if you specify a value higher than 2 in the second argument for the UseTryCatch
pragma. For example, all methods with up to 5 executable statements under the scope
of the following pragma:
are converted using a Try-Catch block.
Important Note: the UseTryCatch pragma can be used together with
the AutoDispose Force pragma, in which case VB Migration Partner generates a complete
Try-Catch-Finally block. However, for the VB.NET code to be perfectly equivalent
to the original VB6 code it is essential that the On Error Goto statement be located
at the very top of the method body.
WrapDeclareWithCallbacks boolean
This pragma requires VB Migration Partner Enterprise edition
Specifies whether VB Migration Partner must generate additional code to ensure that
delegate objects passed to Declare statements aren’t orphaned during garbage
collections:
BringToFront
Changes the z-order of a control and brings it in front of all other controls. This
pragma can be only scoped at the control level. When using this pragma for two or
more controls on the same form, the last control becomes the topmost control:
FormFont fontname [,fontsize]
This pragma requires VB Migration Partner Enterprise edition
Set the default font for a specific form or (if the pragma has project scope) all
the forms in the application. The fontname argument is the name of the
form (embedded in double quotes if contains spaces), the optional fontsize
argument is the size of the font:
This pragma allows you to specify a different default font for forms; it affects
only fonts that use the default font and don’t specify a specific font. If
the fontsize argument is omitted, the original font size is retained.
KeepObsoleteProperties boolean
Specifies whether VB Migration Partner should discard assign design-time assignments
to properties that aren’t supported under VB.NET. Such properties are marked
as obsolete in the control language library and, by default, they aren’t included
in the converted project. If the argument is True or omitted, assignments to these
properties are preserved in the converted VB.NET project:
You can scope this pragma at the project, file, and individual control level. This
pragma can be useful to browse all the properties that are usually discarded during
the migration process.
ReplaceFont oldfontname, newfontname
This pragma requires VB Migration Partner Enterprise edition
Replace all occurrences of a font with another font, for all controls in current
form or in all forms in current project (depending on the pragma’s scope):
VB.NET doesn’t support system fonts, a group which includes the following
fonts: Courier, Fixedsys, Modern, MS Sans Serif, MS Serif, Roman, Script, Small
Fonts, System, and Terminal. Because of this limitation, VB Migration Partner converts
Courier and Fixedsys fonts to Courier New and all other fonts to Arial, while preserving
the font size. You can use this pragma to enforce a different substitution schema.
ReplaceFontSize oldfontname, oldfontsize, newfontname, newfontsize
This pragma requires VB Migration Partner Enterprise edition
Replaces all occurrences of a font/size combination with a different font/size combination,
for all controls in current form or in all forms in current project (depending on
the pragma’s scope):
See the ReplaceFont pragma for more information on the automatic font replacement
mechanism that VB Migration adopts.
SendToBack
Changes the z-order of a control and sends it behind all other controls. This pragma
can be only scoped at the control level. When using this pragma for two or more
controls on the same form, the first control becomes the bottommost control:
WriteProperty propertyname, value
Assigns a design-time property to the current form or to a specific control:
This pragma is useful in many cases, for example to manually assign a control property
that VB Migration Partner can’t migrate correctly (as is the case of the DTPicker’s
Format property) or to purposely introduce minor differences between the VB6 and
VB.NET applications.
TranslateProperties propertylist
This pragma requires VB Migration Partner Enterprise edition
Specifies a list of properties that have a different name in the .frm file. The
propertylist argument is a comma-delimited list of oldname=newname
pairs, as in this example:
When storing properties in a .frm file, VB6 doesn’t necessarily use the property
name; more precisely, the actual name used in the .frm file is equal to the name
specified when saving the value in the WriteProperties event handler. If the name
specified in the event handler is different from the property name, you should use
this pragma to tell VB Migration Partner which name is used in .frm files.
This pragma can’t have a scope prefix and is implicitly scoped at the file
level. It is ignored if it appears in a VB6 file other than a .ctl (user control
) class.
TranslateEvents eventlist
This pragma requires VB Migration Partner Enterprise edition
Specifies a list of events that must be renamed when migrating a UserControl class.
The eventlist argument is a comma-delimited list of oldname=newname
pairs, as in this example:
When this pragma is used, VB Migration Partner marks the converted UserControl class
with a TranslateEvents attribute. In turn, this attribute is taken into account
when VB Migration Partner converts any VB6 form that contains one or more instances
of the user control. Renaming an event is sometimes necessary because the original
name used under VB6 conflicts with events exposed by the .NET UserControl class.
This pragma can’t have a scope prefix and is implicitly scoped at the file
level. It is ignored if it appears in a VB6 file other than a .ctl (user control
) class.
IgnoreMembers memberlist
This pragma requires VB Migration Partner Enterprise edition
Specifies a list of properties and methods that should be ignored when translating
a VB6 user control. The memberlist argument is a pipe-delimited list of
member names:
This pragma can’t have a scope prefix and is implicitly scoped at the file
level. It is ignored if it appears in a VB6 file other than a .ctl (user control
) class.
Note: This group of pragmas allow you to control how VB Migration
Partner parses VB6 statements or outputs VB.NET code. None of these pragmas can
have a scope, because they have an immediate effect on the code that follows.
InsertStatement code
Inserts a statement in the converted application. The code argument is
an (unquoted) string that represents a valid VB.NET statement (or statements):
Note text
Inserts an UPGRADE_NOTE remark in the converted VB.NET:
x = Abs(y) Mod y
OutputMode mode [,count]
Sets VB Migration Partner’s output mode. The mode argument can be
one of the following: On (enables code generation), Off (disable
code generation), Remarks (generate remarked out code)), Uncomment
(removes a leading apostrophe). The count argument is the number of VB.NET statements
affected by this pragma; if zero or omitted, the effect extends to the next OutputMode
pragma:
PrintReport "Products”, 1, 10
Private Sub TestReport()
End Sub
The Uncomment setting is especially useful for including a portion of VB.NET code
that doesn’t exist in the original VB6 project:
ParseMode mode [,count]
Sets VB Migration Partner’s parsing mode. The mode argument can be
one of the following: On (enables parsing), Off (disable parsing),
Remarks (consider next statements as remarks). The count argument is the
number of VB6 statements affected by this pragma; if zero or omitted, the effect
extends to the next ParseMode pragma:
PrintReport "Products”, 1, 10
Private Sub TestReport()
End Sub
Notice the subtle difference between OutputMode and ParseMode pragmas. If parsing
is enabled when a variable or method is parsed, VB Migration Partner creates a symbol
for that method and correctly solves all references to it; if parsing is disabled,
no symbol can be created, which prevents VB Migration Partner from correctly resolving
references to that symbol.
If you don’t want to include a VB6 member in the VB.NET program, in most cases
it is preferable to have VB Migration Partner parse the symbol and then use an OutputMode
pragma to omit it during the code generation phase.
ParseReplace vb6code
Replace the following line of VB6 code with a different line. The replacement is
performed before the parsing takes place, therefore you can use this pragma to change
the way a method is declared, the scope of a variable, and so forth:
Sub Test()
Notice that this pragma replaces an entire line of code, therefore it can replace
multiple statements if the next line contains multiple statements. It can even replace
a portion of a statement if the next line has a trailing underscore.
Rem text
Inserts a remark in the VB6 source code that won’t be translated to VB.NET.
This pragma is useful to explain what other pragmas do:
Dim arr(1 To 10) As Integer
RemoveUnreachableCode mode
This pragma requires VB Migration Partner Enterprise edition
Determines how unreachable code blocks are processed. The mode argument
can be one of the following three values: Off (unreachable code is left
in the generated VB.NET code, the default behavior), On or omitted (unreachable
code is removed from the generated VB.NET code), Remarks (unreachable code
is remarked out.) Consider the following VB6 code:
Sub Test(x As Long, y As Long)
x = 123
Exit Sub
x = 456
y = 789
End Sub
This is the VB.NET code that VB Migration Partner generates:
Sub Test(ByRef x As Integer, ByRef y As Integer)
x = 123
Exit Sub
End Sub
If the VB6 code had included the followed pragma:
then the result would have been as follows:
Sub Test(ByRef x As Integer, ByRef y As Integer)
x = 123
Exit Sub
End Sub
Notice that current version of VB Migration Partner might, under some conditions,
fail to recognize a piece of code as unreachable. This happens, for example, when
a label is referenced by a piece of code that is unreachable. Consider the following
code snippet
Sub Test(ByRef x As Integer, ByRef y As Integer)
x = 123
Exit Sub
Restart:
If x = 10 Then Goto Restart
End Sub
The block of code between Exit Sub and End Sub is unreachable and should be removed.
However, the Restart label is referenced by the GoTo statement in the unreachable
portion of the method, and this detail cheats VB Migration Partner into believing
that the label is indeed reachable. We are aware of this limitation and hope to
work around it in a future release of the tool.
RemoveUnusedMembers removeMode, safeMode
This pragma requires VB Migration Partner Enterprise edition
Determines how unused members blocks are processed. The first argument can be one
of the following three values: Off (unused members are left in the generated
VB.NET code, the default behavior), On or omitted (unused members are removed
from the generated VB.NET code), Remarks (unused members are remarked out.)
The second argument is True if the pragma must affect only members that can’t
be reached via late binding. Consider the following VB6 code:
Const UnusedValue As Integer = 1
If the constant is never referenced, VB Migration Partner generates the following
message:
Const UnusedValue As Integer = 1
If you use a RemoveUnusedMembers pragma, the message is different. For example:
Const UnusedValue As Integer = 1
generates this VB.NET code:
If the On option is used, the warning message is emitted but the member itself is
removed. You need a DisableMessage pragma to drop the warning.
When applied to methods, the RemoveUnusedMembers pragma used with the Remarks disables
a few other refactoring features, for example the ConvertGosubs pragma. In other
words, if the following pragmas are active:
then VB Migration Partner generates (remarked out) nonoptimized VB.NET code, where
Gosub keywords are not rendered as separate methods and On Error statements are
not converted into Try-Catch blocks.
Important note: the RemoveUnusedMembers pragma deletes or remarks
all members that haven’t found to be referenced by any other member in the
current project or other projects in the current solution. However, this mechanism
can lead to unwanted removal if the member is part of a public class that is accessed
by another project (not in the solution) or if the member is accessed via late-binding.
You can use the MarkAsReferenced or
MarkPublicAsReferenced pragmas
to account for the first case.
However, there is no simple way to detect whether a member is accessed via late-binding.
For this reason the RemoveUnusedMembers pragma supports a second safeMode
parameter. If this parameter is True then the pragma affects only members that can’t
be reached via late-binding, e.g. constants, Declare statements, and members with
a scope other than public.
ReplaceStatement code
Replaces the next statement with a piece of code. The code argument is
an (unquoted) string that represents a valid VB.NET statement (or statements):
Dim obj As New Widget
Keep in mind that this pragma replaces only the VB6 statement (not the
line) that follows immediately the pragma. If the following line includes two statements
separated by a semicolon, only the first statement is replaced by this pragma.
Note: This group of pragmas allow you to select which upgrade messages
are generated during the migration process. VB Migration Partner can generate issue,
warning, info, and to-do messages and, by default, all of them are included as remarks
in the converted VB.NET application. You can selectively disable and enable messeges
by their ID, by their severity (Issue, Warning, Info, ToDo), and type (Syntax, Language,
CodeAnalysis, Library)
DisableMessage messageid
Disables generation for a specific message. The messageid argument is the
hex numeric value of the message:
DisableMessages category
Disables message generation for a specific language category. The argument can be:
Info, ToDo, Warning, Issue, Syntax, Language, CodeAnalysis, Library, All:
EnableMessage messageid
Enables generation for a specific message. The messageid argument is the
hex numeric value of the message:
EnableMessages category
Enables message generation for a specific language category. The argument can be:
Info, ToDo, Warning, Issue, Syntax, Language, CodeAnalysis, Library, All:
MarkAsReferenced
This pragma requires VB Migration Partner Enterprise edition
Specifies that a specific symbol should be considered as used even if VB Migration
Partner can’t detected any reference to it. It is useful when the member is
accessed through late binding or the CallByName method:
Notice that this pragma must have a scope prefix.
MarkPublicAsReferenced
This pragma requires VB Migration Partner Enterprise edition
Specifies that all public members of current user control or class should be considered
as used even if VB Migration Partner can’t detected any reference to it. It
is useful inside ActiveX DLL or EXE projects that aren’t migrated together
with their clients:
PreCommand cmdtext
Executes an external application or an operating system command before starting
the conversion of current project; cmdtext is the name of the external
application or O.S. command, including its path if the application can’t be
found on system path. If the command is an internal O.S. command (e.g. Copy) or
the name of a batch file, the command should be prefixed by cmd /C
and be run through the command-line interpreter:
cmdtext can include the following special placeholders (not case sensitive)
${vb6projectfile}
: the complete path+name of the VB6 .vbp project file
${vb6projectpath}
: the path of the folder containing the VB6 .vbp project file
It is a good idea to enclose these placeholders between double quote, in case the
project name or path include spaces. For example, you can use the PreCommand pragma
to restore all VB6 files from a backup folder before starting the migration:
The PreCommand pragma can only have an (implicit or explicit) project scope. You
can apply the PreCommand pragma only by storing it in a *.pragmas file. We suggest
that you use the special file named VBMigrationPartner.pragmas, which you can conveniently
share among all the projects of a complex application, and use project placeholders
to differentiate between individual projects.
PostCommand cmdtext
Executes an external application or an operating system command after saving the
migrated .NET version of current project; cmdtext is the name of the external
application or O.S. command, including its path if the application can’t be
found on system path. If the command is an internal O.S. command (e.g. Copy) or
the name of a batch file, the command should be prefixed by cmd /C
and be run through the command-line interpreter:
cmdtext can include the following special placeholders (not case sensitive)
${vb6projectfile}
: the complete path+name of the VB6 .vbp project file
${vb6projectpath}
: the path of the folder containing the VB6 .vbp project file
${ProjectName}
: the .NET name of the project that has been converted
${ProjectFile}
: the path of the .NET project that has been converted
${ProjectPath}
: the path of the folder containing the converted .NET project
It is a good idea to enclose these placeholders between double quote, in case the
project name or path include spaces. For example, you can use the PostCommand pragma
to copy all VB.NET source files to a backup folder immediately after saving them
The PostCommand pragma can only have an (implicit or explicit) project scope.
The PostCommand pragma is very helpful to preserve one or more .NET “definitive”
source files that have been accurately edited and refined and that you don’t
want to be overwritten in subsequent migrations. VB Migration Partner always deletes
all the files in the target .NET directory, therefore you can’t really prevent
a file from being overwritten; however, you can store all these “definitive”
files in a given folder and use a PostCommand pragma to ensure that these files
are copied over the files produced by the migration that has just been completed:
This technique is especially useful to preserve *.designer.vb files containing the
code-behind portions of converted .NET forms.
SetTag tagname, tagvalue
Creates a tag with a given name and value. This pragma can be only useful when a
VB Migration Partner extender recognizes and uses it. The following example assumes
that you have installed an extender that recognizes the pragma tag named “DatabaseName”