What Is Reg-Free COM - Using COM Without Registration

· · COM, Reg-Free COM, Registration-Free COM, Windows Development, Legacy Technology

In COM / ActiveX / OCX projects, the same mud comes up with every deployment and update.

  • regsvr32 is required
  • Administrator privileges tend to become necessary
  • You collide with a different version installed by another app
  • An uninstall drags down other products with it
  • It works on the development machine but fails in a clean environment

What can significantly reduce this swamp is Reg-Free COM. That said, despite the name, it is not “magic that makes all of COM’s headaches go away.” What it mainly removes is the headaches dragged in by global registration. It does not make the difficulties of bitness, dependent DLLs, type libraries, or threading models disappear.

In this article, we organize Reg-Free COM mainly around the context of keeping COM DLLs / OCXs application-local in Windows desktop apps.

1. The Conclusion First (In One Breath)

Let us start with a rough but useful way of putting it.

  • Reg-Free COM is a way of holding COM registration information in a manifest instead of the registry
  • At runtime, when resolving CoCreateInstance or CLSIDFromProgID, the activation context is consulted first
  • As a result, COM DLLs / OCXs can be kept private per application
  • The main benefits are easy XCOPY deployment, easier avoidance of version conflicts, and uninstalls that are harder to break
  • However, the 32-bit / 64-bit problem does not go away. No amount of willpower gets you past it
  • Also, dependent DLLs, type libraries, design-time references, and non-standard registration dependencies need to be considered separately
  • In practice, it is a very good fit when you want to ship app-specific COM components alongside the app

In short, Reg-Free COM is a mechanism that pulls COM activation back to the per-application level.

2. What This Article Means by Reg-Free COM

Reg-Free COM is short for Registration-Free COM. In Japanese it is sometimes written as “registration-not-required COM.”

“Registration-free” here means not fully depending on global registry registration such as HKCR / CLSID / InprocServer32 in order to use COM. It does not mean that COM itself disappears, nor that GUIDs become unnecessary.

The main subjects of this article are things like the following.

  • Native COM DLLs
  • ATL-based COM servers
  • ActiveX / OCX
  • COM interop based on .NET Framework
  • COM exposure using the .NET 5+ / .NET 8 COM host

Conversely, there are two points this article wants to emphasize.

  1. Reg-Free COM is about “activation”
  2. Distributing type information and configuring design-time references can remain separate issues

Mixing these up muddies the discussion considerably.

3. The Whole Picture on One Page

It is faster to look at the big picture on a single page first.

MyApp.exeApplication ManifestdependentAssemblyComponent / Assembly Manifestfile / comClass / typelibVendorControl.dll / .ocxActivation ContextCLSIDFromProgID / CoCreateInstance

In ordinary COM, calling CoCreateInstance walks the registry to decide which DLL to load. In Reg-Free COM, before that happens, the currently active activation context is consulted, and resolution is done from the manifest information written there.

Because of this, app A and app B on the same machine can more easily run while carrying different versions of the same family of COM components. It nudges COM’s sharing culture slightly back toward being application-local.

4. Why Ordinary COM Deployment Tends to Get Heavy

Ordinary COM deployment is heavy not so much because COM itself is bad, but because of the assumption of global registration.

To use a COM class, roughly this kind of information is required.

Information Role
CLSID GUID that uniquely identifies the class
ProgID Human-friendly name
InprocServer32 Which DLL to load
ThreadingModel Assumptions such as Apartment / Both
TypeLib Type information

Once these go into the registry, they are convenient machine-wide, because they are easy to share across multiple apps.

In practice, however, this sharing backfires.

  • One product’s setup overwrites another product’s COM registration
  • An uninstaller “thinks it only removed its own stuff” and breaks shared COM
  • A registration that happens to exist on the development machine does not exist on the production machine
  • 32-bit and 64-bit registrations fail to mesh, and only the symptoms drift around eerily

In other words, the deployment model troubles people far more often than COM itself does. Reg-Free COM is a mechanism for reducing the pain of this deployment model.

5. How Reg-Free COM Works

5.1 Declare Dependencies in the Application Manifest

First, the app side writes which side-by-side assemblies it depends on into its application manifest.

This manifest can be handled either way:

  • placed next to the EXE, like MyApp.exe.manifest
  • embedded in the EXE as a resource

In practice, a common split is: use an external file if you want deployment and replacement to stay visible, or embed it if you prioritize robustness and simple distribution.

Note that when both an external-file version and an embedded version exist, the manifest on the file system takes precedence.

5.2 Describe COM Information in the Component Manifest

Next, the COM side carries the information that would otherwise live in the registry in a component manifest.

The information that goes in here includes, for example:

  • comClass
  • clsid
  • progid
  • threadingModel
  • typelib
  • if needed, proxy / stub, window classes, and so on

In other words, the idea is to describe the COM component’s face in XML instead of the registry.

This manifest can be configured either way:

  • placed as a separate file alongside the DLL
  • embedded in the DLL as a resource

In practice, embedding it into the DLL as a private assembly tends to cause fewer accidents. Operating with a separate file is easier to understand, but it is easy to trip over the mapping between the file name and assemblyIdentity, the placement location, and missed copies.

5.3 At Runtime, the Activation Context Is Consulted First

This is the heart of Reg-Free COM.

When the app calls CLSIDFromProgID or CoCreateInstance, the COM runtime looks at the active activation context. If the necessary ProgID → CLSID and CLSID → DLL information is there, resolution succeeds without touching the registry.

Conversely, if the manifest lacks the necessary information, it falls back to the usual registration-based resolution. This behavior is what creates the trap of it happens to work on the development machine. You think you have gone Reg-Free, but in reality you are being rescued by a local registration.

This is the nastiest pitfall of Reg-Free COM.

6. What You Gain

In practice, the benefits of Reg-Free COM are quite clear.

6.1 Easy XCOPY Deployment

You can place all the required files together in the app folder, which lightens the installer and registration steps. Of course, if you write under Program Files, permissions are a separate matter, but at minimum you can reduce the administrator work needed for COM registration.

6.2 Easier to Reduce Version Conflicts

Even when multiple versions of a COM component exist on the same machine, it becomes easier to separate which version each app uses. You can largely avoid the accident of behavior suddenly changing because of another product's setup.

6.3 Often Requires Few Changes to Existing Code

Reg-Free COM is a mechanism that changes how resolution happens, rather than fundamentally changing how existing code makes its calls. So when it fits well, you can adopt it with almost no changes to the CoCreateInstance side of the code.

6.4 Removal and Rollback Become Easier

Because everything is contained per app, updates and rollbacks become much more straightforward. Put bluntly, it becomes easier to adopt the mindset of swapping the whole folder.

7. Where It Fits and Where It Does Not

7.1 Situations Where It Fits

In cases like these, Reg-Free COM is a very strong option.

Situation Fit
You want to bundle an app-specific COM DLL / OCX Very good
You want multiple versions coexisting on the same PC Very good
You want to avoid registration accidents with vendor components Good
You want to use an ActiveX / OCX privately in an existing desktop app Good
You want lighter deployment without major changes to existing calls Good

Typically it fits well with line-of-business desktop apps, equipment-integration tools, and existing VB6 / MFC / WinForms assets.

7.2 Situations Where It Does Not Fit, or Deserves Caution

On the other hand, there are cases that warrant a careful look.

Situation Comment
You want to share COM machine-wide The benefits of Reg-Free are thin
Bitness does not match Reg-Free does not solve this
Heavy dependence on non-standard registration info or a custom setup Hard to express in a manifest
Distribution of dependent DLLs or the VC++ runtime is not sorted out You will trip somewhere else anyway
Design-time tools or IDE reference settings assume the registry A separate operational design is needed

The last point in particular matters. Reg-Free COM helps with runtime activation, but it does not instantly change what the design-time reference UI assumes.

8. Common Misconceptions

8.1 “With Reg-Free COM, the Bitness Problem Goes Away”

It does not. A 32-bit process can only load 32-bit in-proc COM DLLs, and a 64-bit process can only take 64-bit DLLs. This is exactly the same under Reg-Free as before.

8.2 “With Reg-Free COM, the Registry Is Never Consulted”

Also wrong. If the manifest lacks the necessary information, resolution falls back to the usual registration-based path. Therefore, success on a development machine does not guarantee the Reg-Free configuration is correct.

8.3 “With Reg-Free COM, the Type Library Story Sorts Itself Out”

This is only half true. A manifest can carry typelib information too, but it is entirely normal for the handling of type information — VBA reference settings, C++ #import, generating design-time references on the .NET side, and so on — to require separate design.

Reg-Free COM is, first of all, about getting things to launch. How to develop with types is the next issue after that.

8.4 “With Reg-Free COM, Any ActiveX / OCX Just Works”

This one is dangerous too. If the component rides on standard COM registration information, you can move forward smoothly, but when it depends heavily on custom registry settings, additional setup, licensing logic, or a cluster of other modules, going Reg-Free suddenly gets rough.

8.5 “Reg-Free COM on .NET Framework and .NET 8 Is Roughly the Same”

There are similarities, but the toolchains differ considerably. The .NET Framework + RegAsm context and the .NET 5+ / .NET 8 + comhost context stand on different footing even though both are COM.

9. Differences Between Native / .NET Framework / .NET 5+ / .NET 8

This is easy to mix up, so let us separate them once.

Family Rough summary
Native COM DLL / OCX Fundamentally a matter of an application manifest plus a component manifest
COM interop based on .NET Framework In addition to a Win32-style application manifest, a manifest is also needed on the managed component side
COM exposure on .NET 5+ / .NET 8 EnableComHosting builds a COM host, and EnableRegFreeCom can generate a Reg-Free manifest

9.1 .NET Framework-Based COM

With .NET Framework-based COM, you end up with a two-tier setup: a Win32-style application manifest on the COM app side and a component manifest on the managed component side.

This area is slightly trickier than native COM. At the point of “I understood Reg-Free COM, but once a managed component gets involved, suddenly one more manifest appears,” the conversational road surface gets a little muddy again.

9.2 COM Exposure on .NET 5+ / .NET 8

On .NET 5+ / .NET 8, the entry point for COM exposure becomes *.comhost.dll. Additionally, setting EnableRegFreeCom=true outputs a side-by-side manifest for Reg-Free COM.

But here too, the important point is that Reg-Free COM and TLB strategy are separate. .NET Core / .NET 5+ is not the world of .NET Framework days where a TLB naturally falls out of the assembly. If you need typed usage, it is safer to sort out TLB generation, embedding, and registration as a separate discussion.

10. A Minimal Configuration Sketch

Here we show a minimal sketch in which MyApp.exe uses Vendor.CameraControl.dll via Reg-Free COM.

10.1 File Layout Sketch

MyApp.exe
MyApp.exe.manifest
Vendor.CameraControl.dll
Vendor.Helper.dll

In the example above, the component manifest is assumed to be embedded in the DLL. A separate file is also fine, but embedding is easier to keep organized at first.

10.2 Application Manifest Sketch

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="KomuraSoft.MyApp"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Vendor.CameraControl.Asm"
        version="1.0.0.0"
        processorArchitecture="amd64" />
    </dependentAssembly>
  </dependency>
</assembly>

10.3 Component Manifest Sketch

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="Vendor.CameraControl.Asm"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <file name="Vendor.CameraControl.dll">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      progid="Vendor.CameraControl.1"
      threadingModel="Apartment"
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}" />

    <typelib
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}"
      version="1.0"
      helpdir="" />
  </file>
</assembly>

What truly matters in this example is not the XML details but that the app-side dependentAssembly and the component-side assemblyIdentity match. If they drift apart, you suffer rather quietly.

Note that the GUIDs and names above are examples for explanation. In reality, you must write them correctly to match the CLSID / TLBID / ProgID / threading model the component actually exposes.

11. Pitfalls

11.1 It Works on the Development Machine but Not on the Target

The first suspect is the pattern of actually being rescued by a registry registration. It is safer to verify Reg-Free COM in a clean environment whenever possible.

11.2 It Fails to Start with “side-by-side configuration is incorrect”

This family of errors comes from manifest inconsistencies, missing dependent DLLs, a missing VC++ runtime, architecture mismatches, and so on. The surface error text alone is fairly unhelpful, so the standard approach is to chase it with the event log and sxstrace.

11.3 The Component Manifest and Application Manifest Drift Out of Sync

  • The name differs
  • The version differs
  • The processorArchitecture differs
  • The manifest you thought you copied is stale

These differences look tiny on the surface, but at startup they hit quite hard.

11.4 Forgetting to Place Dependent DLLs

If you stop at Vendor.CameraControl.dll and feel satisfied, you miss the Vendor.Helper.dll loaded downstream, the VC++ runtime, and the proxy / stub DLLs. Reg-Free COM reduces COM registration problems, but it does not also erase native dependency-resolution problems.

11.5 Postponing Type Library and Reference-Setting Operations

Even after runtime activation goes through, once you need to

  • early-bind from VBA
  • use #import from C++
  • generate interop at design time on the .NET side

you need a way to distribute type information. Reg-Free COM does not arrange all of this automatically, so it is important to think about runtime and design-time separately.

12. Summary

If we had to describe Reg-Free COM in one phrase, it is a mechanism that shifts COM registration information from the whole machine to the per-application level.

This gives you the following benefits:

  • Easier to keep COM DLLs / OCXs application-local
  • Easier to reduce version conflicts
  • Easier to simplify deployment and rollback

On the other hand,

  • 32-bit / 64-bit
  • dependent DLLs
  • TLBs / reference settings
  • non-standard registration dependencies
  • verification in a clean environment

remain just as important.

So the basic posture when adopting Reg-Free COM is this:

  1. Accept that this is about activation
  2. Separate the runtime and design-time issues
  3. Verify in a clean environment
  4. Sort out bitness and dependent DLLs first

Looking at it in this order makes accidents far less likely.

14. References

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog