I have several programs that must write to HKLM in XP and Windows 7/64 Pro.

The programs work in VB6 but not in VB.Net 2008 on target machines. It does works on our development machine.
Same exact windows.
User is an Administrator.
NOT using Run as.

Both programs are using the same function
Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" _
(ByVal lngRootKey As Long, ByVal lpSubKey As String, phkResult As Long)
As Long
Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" _
(ByVal lngRootKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
etc.

for VB6

Changed Long to Integer for VB.NET

It works on the developement machine

VB6 works on BOTH machines.

VB.Net gets no data reading and err 5 trying to write.

On our development machine and also on the target machine the VB6 registry entry goes to
HKEY_CURRENT_USER\Software\Classes\VirtueSTore\Software\Wow6432Node\...

I just cannot figure out why VB6 works but .net doesn't and fails only on the target machine not the development machine.

Thanks

Dani AI

Generated

Likely cause and quick diagnosis (based on ’s observations): the VB6 build was being treated as a “legacy” app and Windows silently redirected its HKLM writes into the per-user Virtual Store, while the VB.Net build is running with a UAC-aware manifest (or otherwise not eligible for virtualization) so it tries to write the real HKLM and gets Access Denied. That explains “VB6 works / VB.Net fails on the target box” and why turning UAC off made the .NET app behave like the VB6 one. See Microsoft’s notes on manifests and virtualization. Application manifests and UAC/virtualization guidance.

Why this happens (short): 32-bit legacy executables that lack a requestedExecutionLevel are eligible for registry virtualization; their writes to HKLM\Software are redirected into the per-user VirtualStore (a HKCU subtree), so reads by the same legacy process succeed. Managed apps built in VS typically embed a manifest (requestedExecutionLevel/asInvoker), which disables that compatibility redirection; those apps therefore see the real HKLM and will fail without elevation. Also remember WOW64 registry redirection (Wow6432Node) when 32-bit vs 64-bit registry views are involved. See Microsoft’s Registry Redirector docs for details. Registry Redirector (Wow6432Node).

Immediate practical fixes and best practice

  • Don’t rely on virtualization. Write per-user settings to HKCU or AppData at runtime; reserve HKLM writes for the installer (which runs elevated). The Microsoft guidance recommends this pattern. UAC guidance for developers.
  • If you must write HKLM at runtime, run that specific process elevated (manifest: requireAdministrator) or perform the write from an elevated helper/installer.
  • For 64-bit vs 32-bit registry control use .NET’s RegistryView when opening HKLM so you target the intended view.

Example VB.Net pattern (check elevation first; this code still requires the process to be elevated to succeed):

Imports Microsoft.Win32

Using base = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
        If(Environment.Is64BitOperatingSystem, RegistryView.Registry64, RegistryView.Registry32))
    Using key = base.CreateSubKey("SOFTWARE\YourCompany\YourApp")
        key.SetValue("InstallPath", "C:\Program Files\YourApp")
    End Using
End Using

Troubleshooting checklist (do not disable UAC permanently)

  • Run the .NET exe elevated to confirm writes succeed (if they do, it’s a permission/virtualization issue).
  • Inspect the per-user virtual store under HKCU\Software\Classes\VirtualStore... for redirected keys.
  • Confirm whether the .NET binary has an embedded manifest (Project → Properties → Application → Manifest). Embedding requestedExecutionLevel disables virtualization. Application manifests.
  • Use the Registry Redirector docs to understand Wow6432Node behavior when diagnosing 32/64-bit differences.

Turning UAC off is not a safe long‑term fix; the correct solutions are either to use per‑user locations or perform machine‑wide changes from an installer/helper that requests elevation.

Turning UAC off (lowest position) makes the .Net work like VB6.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.