Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Patterns for maintaining VB6 code and strategies for migrating to VB.NET with COM interop.
VB6 to VB.NET Migration
Key Differences
' VB6 - Variant typesDim data As Variant
data = 123
data = "Hello"' VB.NET - Strong typing with Option Strict OnOptionStrictOnDim data AsObject' Still avoid when possibleDim number AsInteger = 123DimtextAsString = "Hello"' VB6 - Default properties
Text1.Text = "Hello"
Text1 = "Hello"' Uses default Text property' VB.NET - Explicit properties required
TextBox1.Text = "Hello"' Must be explicit' VB6 - ByRef defaultSub ProcessData(data AsString) ' ByRef by default' VB.NET - ByVal defaultSub ProcessData(data AsString) ' ByVal by defaultSub ProcessData(ByRef data AsString) ' Explicit ByRef' VB6 - On ErrorOn
ErrorHandler
ex Exception
Error
Resume
Next
On
Error
GoTo
' VB.NET - Try-Catch
Try
' Code
Catch
As
' Handle error
End
Try
Common Migration Issues
' VB6 - Fixed-length stringsDim name AsString * 50' VB.NET - Use regular string and PadRightDim name AsString = "John".PadRight(50)
' VB6 - Currency typeDim amount As Currency
' VB.NET - Use DecimalDim amount AsDecimal' VB6 - Control arraysDim TextBox(5) As TextBox
' VB.NET - Use collectionDim textBoxes AsNew List(Of TextBox)()
' VB6 - Let/Set keywordsLet x = 5Set obj = NewMyClass' VB.NET - Assignment without keywordsDim x AsInteger = 5Dim obj AsNewMyClass()
COM Interop from VB.NET
Early Binding (Type Library Reference)
' Add COM reference in project' Tools -> Add Reference -> COM -> Excel Object LibraryImports Excel = Microsoft.Office.Interop.Excel
PublicSub ExportToExcel(data As DataTable)
Dim excelApp As Excel.Application = NothingDim workbook As Excel.Workbook = NothingDim worksheet As Excel.Worksheet = NothingTry
excelApp = New Excel.Application()
workbook = excelApp.Workbooks.Add()
worksheet = CType(workbook.Worksheets(1), Excel.Worksheet)
' Write headersFor col = 0To data.Columns.Count - 1
worksheet.Cells(1, col + 1) = data.Columns(col).ColumnName
Next' Write dataFor row = 0To data.Rows.Count - 1For col = 0To data.Columns.Count - 1
worksheet.Cells(row + 2, col + 1) = data.Rows(row)(col)
NextNext
excelApp.Visible = TrueCatch ex As Exception
MessageBox.Show($"Excel export failed: {ex.Message}")
Finally' Release COM objectsIf worksheet IsNotNothingThen
System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet)
EndIfIf workbook IsNotNothingThen
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook)
EndIfIf excelApp IsNotNothingThen
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp)
EndIfEndTryEndSub
Late Binding (No Type Library)
Imports System.Reflection
PublicSub CreateExcelLateBound()
Dim excelType As Type = Type.GetTypeFromProgID("Excel.Application")
If excelType IsNothingThen
MessageBox.Show("Excel not installed")
ReturnEndIfDim excelApp AsObject = NothingTry' Create COM object
excelApp = Activator.CreateInstance(excelType)
' Call methods via reflection
excelType.InvokeMember("Visible",
BindingFlags.SetProperty,
Nothing,
excelApp,
NewObject() {True})
Dim workbooks AsObject = excelType.InvokeMember("Workbooks",
BindingFlags.GetProperty,
Nothing,
excelApp,
Nothing)
' Add workbook
workbooks.GetType().InvokeMember("Add",
BindingFlags.InvokeMethod,
Nothing,
workbooks,
Nothing)
FinallyIf excelApp IsNotNothingThen
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp)
EndIfEndTryEndSub
COM Object Release Pattern
' ✅ Good: Proper COM object cleanupPublicSub UseComObject()
Dim excelApp As Excel.Application = NothingDim workbook As Excel.Workbook = NothingTry
excelApp = New Excel.Application()
workbook = excelApp.Workbooks.Add()
' Use objectsFinally' Release in reverse order of creationIf workbook IsNotNothingThen
workbook.Close(False)
Marshal.ReleaseComObject(workbook)
workbook = NothingEndIfIf excelApp IsNotNothingThen
excelApp.Quit()
Marshal.ReleaseComObject(excelApp)
excelApp = NothingEndIf
GC.Collect()
GC.WaitForPendingFinalizers()
EndTryEndSub' ❌ Bad: Not releasing COM objects (memory leak)Dim excelApp = New Excel.Application()
excelApp.Workbooks.Add()
' No cleanup - Excel process remains in memory!
Creating COM-Visible .NET Components
COM-Visible Class
Imports System.Runtime.InteropServices
<ComVisible(True)>
<Guid("12345678-1234-1234-1234-123456789012")>
<ClassInterface(ClassInterfaceType.None)>
<ProgId("MyCompany.Calculator")>
PublicClass Calculator
Implements ICalculator
PublicFunction Add(a AsInteger, b AsInteger) AsIntegerImplements ICalculator.Add
Return a + b
EndFunctionPublicFunction Subtract(a AsInteger, b AsInteger) AsIntegerImplements ICalculator.Subtract
Return a - b
EndFunctionEndClass' Interface for COM
<ComVisible(True)>
<Guid("87654321-4321-4321-4321-210987654321")>
<InterfaceType(ComInterfaceType.InterfaceIsDual)>
PublicInterface ICalculator
Function Add(a AsInteger, b AsInteger) AsIntegerFunction Subtract(a AsInteger, b AsInteger) AsIntegerEndInterface
Register for COM
# Register assembly for COM
regasm MyAssembly.dll /tlb /codebase
# Unregister
regasm MyAssembly.dll /u
# Generate type library
tlbexp MyAssembly.dll
Legacy VB6 Patterns to Modernize
Error Handling
' VB6 style (avoid in new code)PublicFunction GetCustomer(id AsInteger) As Customer
OnErrorGoTo ErrorHandler
' Code hereExitFunctionErrorHandler:
MsgBox "Error: " & Err.Description
ResumeNextEndFunction' VB.NET modern stylePublicFunction GetCustomer(id AsInteger) As Customer
Try' Code hereCatch ex As ArgumentException
MessageBox.Show($"Invalid argument: {ex.Message}")
ReturnNothingCatch ex As Exception
MessageBox.Show($"Error: {ex.Message}")
ThrowEndTryEndFunction
' VB6 Collection (avoid in new code)Dim customers AsNew Collection()
customers.Add(customer, "key1")
Dim item = customers("key1")
' VB.NET generic collectionsDim customers = New Dictionary(OfString, Customer)()
customers.Add("key1", customer)
Dim item = customers("key1")
' Or List(Of T)Dim customerList = New List(Of Customer)()
customerList.Add(customer)
Migration Strategy
Incremental Migration
' 1. Start with COM interop wrapper' Wrap VB6 COM component in VB.NETPublicClass VB6Wrapper
Private vb6Component AsObjectPublicSubNew()
vb6Component = CreateObject("VB6Project.Component")
EndSubPublicFunction ProcessData(data AsString) AsStringReturn vb6Component.ProcessData(data).ToString()
EndFunctionEndClass' 2. Gradually replace with native VB.NETPublicClass ModernComponent
PublicFunction ProcessData(data AsString) AsString' New VB.NET implementationReturn data.ToUpper()
EndFunctionEndClass
Best Practices
✅ DO
' Use modern VB.NET features in new codeOptionStrictOnOptionExplicitOn' Release COM objects explicitly
Marshal.ReleaseComObject(comObject)
GC.Collect()
' Use Try-Catch instead of On ErrorTry' CodeCatch ex As Exception
' HandleEndTry' Use generics instead of CollectionsDim items = New List(Of Customer)()
' Use async for I/OAwait File.WriteAllTextAsync("file.txt", content)
❌ DON'T
' Don't use VB6 compatibility moduleImports Microsoft.VisualBasic.Compatibility.VB6 ' Legacy only!' Don't use Option Strict OffOptionStrictOff' Avoid!' Don't use On Error in new codeOnErrorResumeNext' VB6 style' Don't forget to release COM objectsDim excelApp = New Excel.Application()
' ... (no cleanup - memory leak!)' Don't use late binding when early binding availableDim obj = CreateObject("Excel.Application") ' Use typed reference instead