.NET on AWS Blog
Modernize your legacy VB.NET applications: Automated migration to C# using AWS Transform custom
Many enterprises still maintain legacy Visual Basic .NET (VB.NET) applications built on .NET Framework. While these applications continue to serve business needs, organizations face growing challenges: a shrinking VB.NET developer talent pool, limited modern tooling support, and a difficult path to cross-platform .NET modernization. Migrating from VB.NET to C# addresses these challenges by opening access to a larger developer community, better IDE support, and modern language features.
However, manually converting VB.NET code to C# is tedious and error-prone. For instances, every Module needs to become a static class, every Function() lambda becomes =>, every Select Case becomes switch — across potentially thousands of files.
In this post, we walk through using AWS Transform custom to automate the migration of a sample VB.NET .NET Framework 4.8 console application to C#. We show how to create a custom transformation definition, execute the transformation, and verify the results — all with minimal manual effort.
About AWS Transform
AWS Transform custom is an agentic AI service that performs large-scale modernization of software, code, libraries, and frameworks. It handles API and service migrations, language version upgrades, framework upgrades, code refactoring, and organization-specific transformations.
AWS Transform custom offers out-of-the-box (AWS-managed) transformations for common scenarios such as Java SDK v1 to v2 upgrades, Node.js and Python version upgrades, Angular to React migration, and more. While VB.NET Framework to C# on .NET Framework is not currently in the list of AWS-managed transformations, AWS Transform custom can still perform this kind of conversion. With AWS Transform custom, you define a transformation using natural language, and the AI agent executes it against your codebase.
After migrating to C# .NET Framework, you can further use AWS Transform Full-Stack Windows Modernization to convert the C# .NET Framework application to C# on cross-platform .NET (such as .NET 10). AWS Transform Full-Stack Windows Modernization supports both VB.NET and C# as source languages, so you can choose to port your VB.NET Framework application directly to cross-platform .NET without converting to C# first, or follow the two-step approach described in this post.
Solution overview
This is the migration workflow:
- Start with a VB.NET .NET Framework 4.8 application
- Use AWS Transform custom to convert VB.NET to C# on .NET Framework 4.8
- Optionally, use AWS Transform Full-Stack Windows Modernization to port C# .NET Framework to cross-platform .NET
The AWS Transform custom workflow follows these phases:
- Define — Create a transformation definition describing the VB.NET to C# conversion rules in natural language
- Plan — The AI agent analyzes the codebase and generates a step-by-step execution plan
- Execute — The agent transforms files incrementally, verifying the build after each step
- Validate — Confirm all exit criteria are met: successful build, no remaining VB.NET syntax, preserved API signatures
Prerequisites
- An AWS account with AWS Transform custom access configured
- AWS Transform CLI (atx) installed – requires Node.js 22+ and Git (see the Request Software section in AWS Transform Getting Started)
- .NET Framework 4.8 SDK and MSBuild
- A Windows environment, either native (Windows Terminal with PowerShell) or with WSL2
Environment setup: Windows EC2 Instance
The .NET Framework build toolchain (MSBuild) is required for the AWS Transform custom process to verify the converted C# code, so we ran the AWS Transform CLI (atx) on a Windows EC2 instance for the sample application in this blog post.
You now have two options for where atx itself runs. As of version 3.5.0 (July 2026), atx runs natively on Windows using Windows Terminal and PowerShell — WSL is no longer a requirement. If you go native, atx and MSBuild share the same environment, there is no /mnt/c/ path translation between them, and you are free to pick any general-purpose instance type.
* Use atx 3.6.0 or later, which fixes a Windows issue where paths containing ~ (home directory) resolved to an unexpected directory mid-session.
WSL2 remains fully supported and is still a reasonable choice if you prefer a Linux-style shell. Bash-based scripts, standard GNU tooling — and the commands in the rest of this post are written in that style. Note that the continuous modernization commands (atx ct) are not yet supported on native Windows. This post only uses the AWS Transform custom commands, which work in both environments.
We used WSL2 for this walkthrough, so the commands that follow assume a bash shell. If you are on native Windows, the same commands work with PowerShell equivalents for shell syntax. The setup we used involves:
1. Launch a Windows EC2 instance
- For WSL2, choose an instance type that supports nested virtualization — we used m8i.xlarge.
- If you run atx natively on Windows instead, nested virtualization is not needed and any suitably sized general-purpose type works.
2. Install WSL2 on the Windows instance
3. Install atx within WSL2
4. Install .NET Framework 4.8 SDK and MSBuild on the Windows host
- For WLS2, they need to be accessible via
/mnt/c/
Sample application
We use a sample VB.NET console application — an Employee Management System — to demonstrate the migration. The source code is available on GitHub in the aws-samples organization:
- Repository: sample-aws-transform-custom-vb-to-csharp
- main branch: Original VB.NET source code — browse on GitHub
- atx-result-staging-20260403_074329_289c738e branch: C# code converted by AWS Transform custom — browse on GitHub
The atx-result-staging-20260403_074329_289c738e branch was created and committed automatically by atx as a local branch during the transformation process. It was then pushed to the remote repository manually.
Application structure
The application targets .NET Framework 4.8 and includes the following components:
SampleConsoleApp/ ├── Program.vb # Main entry point (Module) ├── SampleConsoleApp.vbproj # VB.NET project file ├── Models/ │ ├── Employee.vb # Employee model with IComparable(Of T) │ └── Department.vb # Department model with validation ├── Services/ │ ├── EmployeeService.vb # CRUD operations with LINQ queries │ └── ReportService.vb # Report generation with LINQ grouping ├── Utilities/ │ └── ConsoleHelper.vb # Console helper (NotInheritable Class) └── My Project/ └── AssemblyInfo.vb # Assembly metadata
The application demonstrates VB.NET language features commonly found in enterprise applications:
- Modules (
Module Program) - Explicit properties with validation logic
- Interface implementation (
IComparable(Of Employee)) - LINQ method chains with lambda expressions (
Function(e) e.Salary) Select CasestatementsNotInheritable Class(sealed classes)Sharedmethods (static methods)Try...Catcherror handling- Optional parameters
- String concatenation with & operator
Walkthrough
Step 1: Start AWS Transform custom
Launch atx from WSL on the Windows EC2 instance. The interactive CLI displays available AWS-managed transformations and accepts natural language commands.
ubuntu@EC2AMAZ-S6OK3KG:~$ atx
█████╗ ██╗ ██╗███████╗ ██╔══██╗██║ ██║██╔════╝ ███████║██║ █╗ ██║███████╗ ██╔══██║██║███╗██║╚════██║ ██║ ██║╚███╔███╔╝███████║ ╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝ ████████╗██████╗ █████╗ ███╗ ██╗███████╗███████╗ ██████╗ ██████╗ ███╗ ███╗ ╚══██╔══╝██╔══██╗██╔══██╗████╗ ██║██╔════╝██╔════╝██╔═══██╗██╔══██╗████╗ ████║ ██║ ██████╔╝███████║██╔██╗ ██║███████╗█████╗ ██║ ██║██████╔╝██╔████╔██║ ██║ ██╔══██╗██╔══██║██║╚██╗██║╚════██║██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║ ██║ ██║ ██║██║ ██║██║ ╚████║███████║██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
┌──────────────────────────────────────────────────────────────────────────────┐ │ Region: us-east-1 │ └──────────────────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────────────────┐ │ Trusted Tools │ │ │ │ Built-in Trusted Tools │ │ Configuration: Built-in read-only tools │ │ • file_read │ │ • get_transformation_from_registry │ │ • list_available_transformations_from_registry │ │ • document_manager (add operations only) │ │ • editor (view and find_line operations only) │ └──────────────────────────────────────────────────────────────────────────────┘
Welcome to AWS Transform. You can discover, create, and execute transformations (AWS-managed or custom ones published to your registry). How can I help?
> please transform the current directory from VB.NET to C#.NET
Step 2: Create the transformation definition
When you ask atx to transform VB.NET to C#, it first checks the transformation registry for an existing AWS-managed transformation. The agent calls list_available_transformations_from_registry and finds 13 AWS-managed transformations — but none for VB.NET to C#. The agent recognizes the gap and decides to create a custom transformation definition:
> I don't see an existing VB.NET to C# transformation in the registry. Let me create a custom one for you. I'll build a transformation definition for this migration. To make this transformation definition as effective as possible, it would be useful to know: 1. Are there any specific VB.NET patterns or libraries your codebase relies on heavily? 2. Which .NET version are you targeting for the C# output? > 1. No, 2. .NET Framework 4.8
After you provide the answers, atx generates a comprehensive transformation definition as a markdown file. The definition includes an objective, entry criteria, 20 detailed implementation steps, and 8 validation/exit criteria. Here is a snippet of the generated transformation definition:
Using tool: editor (trusted)
⋮
● Path: ~/.aws/atx/custom/20260403_074329_289c738e/artifacts/tp-staging/transformation_definition.md
● Command: create
● File content:
# VB.NET to CSharp.NET Migration
## Objective
Transform VB.NET source files (.vb) into equivalent C#.NET source files (.cs) targeting .NET Framework 4.8, preserving all original functionality, logic, and application behavior while producing idiomatic C# code.
## Summary
This transformation converts an entire VB.NET codebase to C#.NET by translating all language-specific syntax, constructs, and patterns to their C# equivalents. The process covers file-by-file conversion of namespaces, classes, modules, data types, control flow statements, error handling, LINQ expressions, events, delegates, properties, operators, and other VB.NET idioms. The output must compile against .NET Framework 4.8 and maintain identical runtime behavior to the original VB.NET code.
## Entry Criteria
1. The source codebase contains VB.NET source files (.vb) targeting .NET Framework 4.8 or compatible versions.
2. The VB.NET project compiles and builds successfully before transformation.
3. Project files (.vbproj) and solution files (.sln) are present and properly configured.
## Implementation Steps
1. Convert all VB.NET project files (.vbproj) to C# project files (.csproj), translating MSBuild properties and items accordingly. Update the solution file (.sln) to reference the new .csproj files.
2. Convert namespace and imports declarations: replace VB.NET "Imports" statements with C# "using" directives. Translate "Namespace ... End Namespace" blocks to C# "namespace { }" syntax.
3. Convert class, structure, and module declarations:
- Translate "Class ... End Class" to "class { }".
- Translate "Structure ... End Structure" to "struct { }".
- Translate "Module ... End Module" to "static class { }" with all members made static.
...
## Validation / Exit Criteria
1. All VB.NET source files (.vb) have been converted to corresponding C# source files (.cs).
2. The converted C# project compiles successfully against .NET Framework 4.8 with no build errors.
3. All namespaces, class hierarchies, interfaces, and type relationships are preserved in the C# output.
4. All public and internal API signatures (method names, parameters, return types, access modifiers) remain functionally equivalent.
5. Control flow logic, error handling, and exception behavior are preserved and functionally identical.
6. Event handling, delegate usage, and LINQ queries produce the same results as the original VB.NET code.
7. All existing unit tests, if present, pass against the converted C# code with equivalent test coverage.
8. No VB.NET-specific syntax or constructs remain in the C# output files.
● Completed in 2ms
The agent then confirms the definition covers the full breadth of conversion concerns:
The transformation definition for VB.NET to C#.NET has been created and saved. It covers the full breadth of conversion concerns targeting .NET Framework 4.8, including: - Project and solution file conversion (.vbproj to .csproj) - Namespace, imports, and module translations - Data type mappings (Integer to int, Boolean to bool, etc.) - Method, property, and indexer conversions - Control flow (If/Select Case/For/While/With/Using) - Error handling (structured Try-Catch and legacy On Error patterns) - Events, delegates, WithEvents/Handles, AddHandler/RemoveHandler - LINQ query syntax and lambda expression translation - Operator mappings (AndAlso to &&, OrElse to ||, string concatenation, etc.) - String function conversions, XML literals, preprocessor directives, attributes, generics, enumerations - VB.NET-specific constructs like ReDim, My namespace, Option Strict/Explicit, and case-sensitivity resolution
Finally, the agent saves the transformation definition as a draft to the registry:
Using tool: save_transformation (requested) ⋮ ● Name: VB.NET-to-CSharp.NET ● Description: Transform VB.NET code to C#.NET, converting all VB.NET source files to equivalent C#.NET code including project files, syntax, data types, control flow, error handling, LINQ, events, delegates, and all VB.NET-specific constructs. ● Publish: No (Draft) ● New Transformation: Yes ● Completed in 3.1s
The transformation definition is saved and can be reused across multiple projects. You can also publish it to the registry so other team members can use it.
Step 3: Execute the transformation
After saving the transformation definition, atx analyzes the codebase and generates a transformation plan. First, it reads all source files and runs an initial build verification:
> The VB.NET project builds successfully. Now I have a complete understanding of the codebase. Let me create the transformation plan. **Codebase Analysis Summary:** - **Project type:** VB.NET Console Application targeting .NET Framework 4.8 - **Solution:** SampleConsoleApp.sln with a single project SampleConsoleApp.vbproj - **Build tool:** MSBuild (accessible via `MSBuild.exe`) - **Files to convert (7 VB.NET files):** - `Models/Department.vb` - Department class (base model, no dependencies on other project files) - `Models/Employee.vb` - Employee class (depends on Department, implements IComparable) - `Utilities/ConsoleHelper.vb` - Static utility class (no dependencies on other project files) - `Services/EmployeeService.vb` - Employee service (depends on Employee) - `Services/ReportService.vb` - Report service (depends on Employee, Department, ConsoleHelper) - `Program.vb` - Main module (depends on all other classes) - `My Project/AssemblyInfo.vb` - Assembly info - **Project/Solution files to convert:** SampleConsoleApp.vbproj → SampleConsoleApp.csproj, SampleConsoleApp.sln update - **Key VB.NET constructs to convert:** Module (→ static class), Option Strict/Explicit, Imports, NotInheritable, vbCrLf, string concatenation with &, Function lambdas, OrElse/AndAlso, TryCast, CInt, NameOf, Optional parameters, Do...Loop While **Dependency hierarchy (bottom-up):** 1. Department (no dependencies) 2. ConsoleHelper (no dependencies) 3. Employee (depends on Department) 4. EmployeeService (depends on Employee) 5. ReportService (depends on Employee, Department, ConsoleHelper) 6. Program (depends on all)
The agent then creates a 4-step execution plan and presents a summary:
| Step | Title | Key Actions |
| 1 | Convert project/solution infrastructure | .vbproj → .csproj, update .sln, AssemblyInfo.vb → AssemblyInfo.cs |
| 2 | Convert base model classes | Department.vb → .cs, Employee.vb → .cs |
| 3 | Convert utility and service classes | ConsoleHelper.vb, EmployeeService.vb, ReportService.vb → .cs |
| 4 | Convert entry point, cleanup, final build | Program.vb (Module) → Program.cs (static class), remove all .vb f |
After approving the plan, the agent sets up version control and begins the implementation:
Using tool: vcs_control (requested) ⋮ ● Action: setup ● Repository: /mnt/c/aws-samples/sample-aws-transform-custom-vb-to-csharp ● Current Branch: main ● Will Create Branch: atx-result-staging-20260403_074329_289c738e ● Note: Creates a new branch for transformation commits (original branch preserved) ⋮ ● Completed in 628ms
Each step corresponds to a commit made by atx on the atx-result-staging-20260403_074329_289c738e branch. You can review the exact changes for each step on GitHub:
| Step | Commit message | GitHub link |
| 1 | Step 1: Convert project files and solution configuration | 8af77e1 |
| 2 | Step 2: Convert base model classes (Department.vb and Employee.vb) | c626517 |
| 3 | Step 3: Convert utility and service classes | ccd51e3 |
| 4 | Step 4: Verify the results | 24187ca |
After all steps complete, the validation summary confirms:
- 7 VB.NET files converted to 7 C# files
- Project infrastructure migrated (
.vbproj→.csproj,.slnupdated,AssemblyInfomigrated) - All original
.vbfiles removed - Build succeeded with 0 errors and 0 warnings
- All public API signatures preserved
- No VB.NET-specific syntax remaining in any .cs file
================================================================================ TRANSFORMATION COMPLETE ================================================================================ All 4 steps executed successfully. The VB.NET codebase has been fully converted to C#.NET. Summary of conversion: - 7 VB.NET files converted to 7 C# files - Project infrastructure migrated (.vbproj -> .csproj, .sln updated, AssemblyInfo migrated) - All original .vb files and VB.NET project artifacts removed - Full build succeeds with 0 errors and 0 warnings - All public API signatures preserved - All business logic preserved identically ● Completed in 0ms
Before and after: Code comparison
Let’s look at some key conversion examples to see what AWS Transform custom produced.
Module to static class
VB.NET (Program.vb):
C# (Program.cs) — converted by AWS Transform custom:
Key conversions: Module → static class, all members made static, Select Case → switch, While...End While → while { }, Dim → explicit type declarations.
Interface implementation and properties
VB.NET (Employee.vb):
C# (Employee.cs):
Key conversions: Implements IComparable(Of Employee) → : IComparable<Employee>, Me. → this., Is Nothing → == null, & → +, Implements clause removed from method signature.
LINQ and lambda expressions
VB.NET (EmployeeService.vb):
C# (EmployeeService.cs):
Key conversions: List(Of Employee) → List<Employee>, Function(e) → e =>, OrElse → ||.
Sealed class with static methods
VB.NET (ConsoleHelper.vb):
C# (ConsoleHelper.cs):
Key conversions: NotInheritable → sealed, Shared → static, Optional parameters → C# optional parameters, "-"c → '-'.
Comprehensive conversion reference
The following table summarizes the VB.NET to C# conversions that AWS Transform custom handled in this migration:
| VB.NET construct | C# equivalent |
Module ... End Module |
public static class { } |
Sub ... End Sub |
void Method() { } |
Function ... End Function |
ReturnType Method() { } |
Dim x As Type |
Type x |
Shared |
static |
NotInheritable |
sealed |
Overrides |
override |
ReadOnly (property) |
Get-only property |
Implements IComparable(Of T) |
: IComparable<T> |
Select Case ... End Select |
switch { case: break; } |
If ... Then ... End If |
if (...) { } |
While ... End While |
while (...) { } |
For Each ... Next |
foreach (...) { } |
Do ... Loop While |
do { } while (); |
Try ... Catch ... End Try |
try { } catch { } |
Function(e) e.Property |
e => e.Property |
AndAlso / OrElse |
&& / || |
Is Nothing / IsNot Nothing |
== null / != null |
Not |
! |
& (string concatenation) |
+ |
TryCast(obj, Type) |
obj as Type |
CInt(...) |
(int)(...) |
Me. |
this. |
vbCrLf |
"\r\n" |
Throw New |
throw new |
NameOf(x) |
nameof(x) |
Optional param As Type = val |
Type param = val |
"-"c (Char literal) |
'-' |
500000D (Decimal literal) |
500000m |
Imports |
using |
Next steps: From .NET Framework to cross-platform .NET
After converting your VB.NET application to C# on .NET Framework, the next step in your modernization journey is porting to cross-platform .NET. AWS Transform Full-Stack Windows Modernization can help with this. It provides AI-driven capabilities to:
- Port .NET Framework (C# / VB.NET) applications to cross-platform .NET (such as .NET 8 / 10)
- Modernize SQL Server databases to Amazon Aurora PostgreSQL
- Update UI frameworks from ASP.NET Web Forms to Blazor
- Deploy applications to Amazon EC2 Linux or Amazon ECS
This two-step approach:
- First VB.NET to C# using AWS Transform custom,
- Then C# .NET Framework to cross-platform .NET using AWS Transform Full-Stack Windows Modernization
provides a clear, incremental path to fully modernize your legacy VB.NET Framework applications. This process results in a modernized C# application (NOT VB.NET) running on cross-platform .NET, ready for deployment on Linux or containers.
Clean up
If you launched a Windows EC2 instance for this walkthrough, terminate it to avoid ongoing charges. No other AWS resources are created during the AWS Transform custom process beyond the EC2 instance.
Conclusion
In this post, we demonstrated how to use AWS Transform custom to automate the migration of a VB.NET .NET Framework application to C#. The AI agent created a comprehensive transformation definition, generated a step-by-step execution plan, converted 7 source files with zero build errors, and preserved all business logic and API signatures.
AWS Transform Custom reduces the manual effort and risk involved in language migrations. The transformation definition is reusable — once created, you can apply it across multiple VB.NET projects in your organization. Combined with AWS Transform Full-Stack Windows Modernization for the subsequent .NET Framework to cross-platform .NET migration, you have a complete modernization path for your legacy VB.NET applications.
The sample source code used in this post is available in the aws-samples GitHub organization at sample-aws-transform-custom-vb-to-csharp. To get started with, visit the AWS Transform getting started guide or learn more about AWS Transform custom.