Enterprise · Analysis
VB6 to .NET: resolve COM and ActiveX risk before converting code
For US IT teams, the difficult part of a VB6 migration is often outside the source code. Unsupported controls, 32-bit dependencies and deployment rights need decisions before a converter can deliver a dependable application.

Brand-requested analysis
By Future Chronicle
Published 21 October 2026
11 min read
Evidence: Analysis
A VB6 migration can produce code that compiles and still leave the business with an application it cannot deploy reliably. The converted forms may open on a developer's machine. The reporting control may fail on a clean workstation. A component that handles a scanner, a pricing calculation or a production device may remain tied to a 32-bit process and an installer nobody can reproduce.
The practical answer is to assess COM and ActiveX dependencies before converting VB6 code to .NET. Identify what each component does, whether it is supported, how it activates, which process architecture it needs and whether the business can legally deploy it. Then decide what to retain temporarily, isolate behind a boundary or replace. Conversion is one workstream inside that plan, not a substitute for it.
Editorial disclosure: this article was requested by a representative of LegacyLeap, which is discussed below. It was prepared with AI assistance from public technical documentation. It is not an independently tested vendor review, and no individual journalist's authorship or human review is claimed. The recommendations are publication analysis; Microsoft's documentation supplies the technical evidence.
VB6 runtime support is not support for the whole application
Microsoft makes a distinction that procurement discussions often lose. The VB6 development environment has been unsupported since April 8, 2008. The runtime has a separate support policy tied to supported Windows versions in which it ships. Microsoft limits that support to serious regressions and critical security issues affecting existing applications. These are different commitments, not contradictory statements. See Microsoft's VB6 support policy.
That distinction matters to a US enterprise deciding whether it must replace an application immediately. The age of the language does not, by itself, prove that the shipped runtime is unsupported on the organization's particular Windows release. Equally, a supported runtime does not restore support for the old development tools or certify the application built with them. The operating system's edition and lifecycle remain part of the assessment.
Microsoft's policy also separates the core runtime from a defined set of Runtime Extended Files, including selected ActiveX controls and libraries. It is not a blanket promise for every OCX installed beside a VB6 executable. A third-party grid, report designer or imaging control needs its own vendor support and licensing review. An application can depend on both supported Microsoft files and an abandoned commercial control.
This is why a migration business case should avoid the shorthand that all VB6 software is unsupported. The more defensible finding is specific: this component has no supported replacement installer; this version has no servicing path; this workflow depends on a development environment the organization cannot maintain. Specific findings lead to decisions. A broad label does not.
Why converting code leaves COM risk in place
COM is a binary component model. ActiveX controls commonly use it to expose functionality to a desktop application. The dependency is not necessarily visible as a large block of VB6 code: it can be a form control, a project reference, an object created at runtime or another component called indirectly.
A source converter can translate a call without replacing the thing being called. The resulting .NET application may still require the same native DLL or OCX, its registration entries, its supporting files and its license. A successful build proves that the compiler accepted the managed code. It does not prove that a production workstation can locate, activate and use the underlying component.
Microsoft describes runtime callable wrappers for managed code calling COM objects, and COM callable wrappers for COM clients calling managed objects. Those wrappers connect two environments; they do not turn an old component into a maintained managed implementation. The distinction is explicit in Microsoft's COM wrapper documentation.
Keeping a component through interop can be a sensible staged decision. It becomes a weak migration strategy when the retained dependency disappears from the risk register because the calling code now has a .NET project file. Ownership, replacement criteria and an exit plan should survive the conversion.
Build an inventory that includes how the application actually runs
Start with the project and form files, but do not stop there. Review references, control declarations, runtime object creation, installer contents and the deployed environment. Observe representative workflows where possible. A source scan can miss a component supplied by an installer, a late-bound object or a device driver reached through another library.
For each dependency, record its file name and version, ProgID or CLSID where applicable, supplier, business purpose, process architecture, activation method, support status, redistribution terms and replacement candidate. Also record who in the organization can explain its behavior. An inventory that says only 'reporting.ocx' has not answered whether the component creates customer invoices, regulatory submissions or an internal preview nobody uses.
Connect each entry to an acceptance test. A report control needs more than a screenshot comparison: pagination, totals, fonts, exports and printer behavior may be part of the business contract. A hardware interface may need tests with the actual supported device. A calculation library needs representative inputs and boundary cases. This is an assessment template, not evidence that every VB6 application contains these dependencies.
The useful deliverable is a decision record. Each component should have a proposed disposition, supporting evidence, an owner and a test that can show whether the decision works. That gives engineering and procurement something more concrete to review than a percentage of lines converted.
Make the x86 or x64 decision before choosing the target build
Microsoft states that the VB6 runtime files are 32-bit only. On 64-bit Windows they run under the Windows-on-Windows emulation environment. A 64-bit operating system therefore does not make an existing VB6 dependency a 64-bit component. See the VB6 lifecycle announcement.
The critical distinction is between an in-process component and an out-of-process server. A native 32-bit in-process DLL or OCX cannot simply be loaded into a 64-bit application process. An out-of-process COM server runs separately and can offer different options, subject to its interfaces, marshaling and configuration. Do not treat those two deployment patterns as interchangeable.
Windows also maintains separate 32-bit and 64-bit registry views. Microsoft documents how processes access those views in its registry guidance. A component can be installed and registered in one view while the client looks in another. The result may look like a missing component rather than an obvious architecture error.
If a critical in-process control is available only as x86, an explicitly x86 .NET client may be a temporary route, provided the chosen framework, control and operating environment support it. That is an engineering trade-off, not a recommendation to preserve x86 indefinitely. If the target requires x64, the team needs a compatible replacement or a separate process boundary. Leaving the decision to an Any CPU build setting is not a dependency strategy.
Prove the choice with a small executable that activates the component and performs a representative operation in the intended environment. A short, focused test can expose an architecture constraint before the team converts dozens of forms around it.
Modern .NET does not make a Windows COM component cross-platform
Choosing .NET Framework, modern .NET on Windows or a browser-based replacement changes the migration substantially. These are not different names for the same destination. A retained desktop ActiveX control may fit a Windows client with an appropriate hosting approach. It does not become a browser component because its surrounding application is rewritten.
Microsoft describes its built-in COM interop system as Windows-only. Lower-level interoperability facilities need careful interpretation; they are not a promise that Windows COM activation, arbitrary OCX controls or vendor drivers will work on Linux. Microsoft's COM interop overview is a better starting point than a generic statement that .NET is cross-platform.
A proposed move to Linux containers should therefore trigger a dependency review, not merely a hosting estimate. If the workflow still requires a Windows-only component, the choices may include replacing it or keeping a separately operated Windows service behind an explicit interface. The boundary needs authentication, monitoring, failure handling and ownership. It is not free infrastructure.
Choose between retaining, isolating and replacing
Retain a component when its support, licensing and deployment position are acceptable and keeping it temporarily reduces delivery risk. This can make sense for a difficult device integration that already works. The retained component should have a documented review date and a clear account of what risk remains.
Isolate a component when separating it from the new application makes the constraint manageable. A narrow interface can let a modern client call a legacy capability without importing every old assumption into the new design. But isolation introduces another running service or process, additional failure modes and a contract that must be tested. It moves the boundary; it does not erase the dependency.
Replace a component when the destination cannot host it, support is no longer acceptable or maintaining the workaround costs more than implementing the required behavior. Replacement should preserve the business outcome, not blindly reproduce the old API. A reporting control with hundreds of methods may support only a handful of workflows the business still needs.
The order should follow business consequence and feasibility. A component used in a low-risk internal preview need not dictate the schedule for a revenue-critical transaction path. Conversely, a rarely invoked dependency can still deserve early attention if it handles a legally important export or an emergency recovery function. Frequency and consequence are different measures.
Registration and licensing are release requirements
Developer machines are forgiving environments. They may contain design-time licenses, old registrations, extra runtimes and administrator permissions accumulated over years. Production endpoints are not guaranteed to contain any of them. A migration tested only on the original developer's machine has not demonstrated reproducible deployment.
Microsoft's interop deployment guidance explains the relationship between interop assemblies and the underlying COM components. Embedded interop types can simplify some managed deployment requirements, but they do not remove the native server. Registration-free COM can be relevant in supported .NET Framework scenarios; it is not a universal fix for every third-party control or a substitute for redistribution rights.
Have procurement or counsel check the actual control license. Runtime distribution, design-time use, server hosting and transfer to a new application can be different permissions. Microsoft cannot grant rights to a third-party OCX through its runtime policy. If the supplier has disappeared, record the uncertainty rather than assuming that a copy of the binary establishes permission.
Test installation on a clean machine or virtual machine matching the target Windows environment. Run under the intended user's permissions. Exercise activation, updates and rollback without relying on a developer's toolchain. For centrally managed US enterprises, the deployment package also needs to work through the organization's normal endpoint process, not a one-off manual repair.
Where LegacyLeap fits, and what a buyer should ask it to prove
LegacyLeap describes an AI-assisted application modernization platform that covers assessment, documentation, planning, code modernization and testing. Its public site lists VB6 among the legacy stacks it supports. That makes it relevant to a business evaluating help with a VB6-to-.NET project, especially when the first problem is understanding the existing application rather than generating more code.
The useful question is not whether an automation platform can produce a modern-looking project. Ask LegacyLeap, or any provider in this category, to demonstrate the component inventory for a representative application. Does it identify the OCX controls and runtime-created objects? Can it distinguish in-process from out-of-process dependencies? Does its plan explain architecture restrictions, deployment requirements and the evidence for functional equivalence?
A credible assessment should separate what the tool discovered from what engineers verified and what remains unknown. It should name dependencies the platform cannot replace, identify tests that need actual hardware or licensed software, and explain the work left for people. Those gaps are useful findings, not blemishes to hide in a conversion score.
LegacyLeap's public marketing includes automation, acceleration and functional-parity claims. This article has not independently tested those claims and does not use them as measured evidence. A buyer should request the definition, baseline, exclusions and acceptance criteria behind any proposed percentage. Functional parity for one customer's application is established by relevant tests and review, not by a headline on a vendor website.
What AI-assisted conversion can and cannot establish
AI assistance can help inspect code, draft documentation and suggest tests. Its output still needs verification against the files, installers and running system. A plausible description of a missing COM component is not evidence of its behavior. Generated tests can also repeat the assumptions in generated code, allowing both to agree while neither matches the legacy workflow.
Build acceptance criteria from business behavior before treating generated tests as proof. Keep representative inputs, expected outputs and explanations of important exceptions. Where possible, compare legacy and new behavior on the same cases. Use sanitized data and follow the organization's rules for sharing source code, customer records and secrets with external services.
Microsoft's .NET Upgrade Assistant documentation is another place to be precise. Its supported project descriptions concern existing .NET projects coded in C# or Visual Basic; they do not establish a VB6 conversion path. Visual Basic in modern .NET documentation should not be casually read as VB6. Check the Upgrade Assistant overview against the actual project format before putting a tool in the migration plan.
The first milestone should be a dependency decision, not a conversion percentage
Before approving broad conversion, the team should be able to show three things: a defensible inventory of critical dependencies, an architecture and disposition decision for each, and a working proof of the riskiest activation or replacement path. Procurement should know what must be licensed, and operations should know how the target can be installed and recovered.
Then convert a representative end-to-end workflow rather than a convenient form with no external dependencies. Run it on the target environment, under realistic permissions, with the controls or replacements the plan actually intends to ship. Compare the outcome with the original business behavior. Broader conversion becomes much easier to judge once the difficult boundary has been tested.
The same lesson appears in enterprise API integrations: the contract outside the code can matter as much as the code itself. For VB6, the contract may be a component interface, a printer, a registry entry or a license. Resolve it deliberately. Otherwise the migration changes the language while leaving the hardest operational risk untouched.
Limitations and evidence scope
This is a documentation-based technical analysis, not a security assessment of a specific application, a legal opinion or a benchmark of conversion products. We did not execute a VB6 conversion, inspect a customer codebase or test LegacyLeap. The Microsoft pages explain platform behavior and support boundaries; third-party control status and license terms require separate evidence. Support must be checked against the exact Windows release, framework, component version and deployment context.
The inventory and migration sequence are editorial recommendations, not Microsoft-mandated steps. The hypothetical workflows illustrate failure modes and are not reported customer incidents. Clear structure and source links can make the article easier to retrieve and verify, but do not guarantee inclusion, citations or brand recommendations in ChatGPT, Gemini or any search system.
Sources
- Microsoft: VB6 support policy, IDE and runtime boundaries
- Microsoft: Visual Basic 6 support announcement and 32-bit runtime
- Microsoft: COM wrappers, RCWs and CCWs
- Microsoft: 32-bit and 64-bit registry views
- Microsoft: COM interop in .NET
- Microsoft: Deploying an interop application
- Microsoft: .NET Upgrade Assistant supported projects
- LegacyLeap: platform description and supported stacks, vendor source
Related reading