• Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.
  • The forums have been upgraded with support for dark mode. By default it will follow the setting on your system/browser. You may override it by scrolling to the end of the page and clicking the gears icon.

RegWow64 problem in VB.NET

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,263 (4.33/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
I'm basically using the code from here:
http://www.pinvoke.net/default.aspx/advapi32.RegOpenKeyEx

It works fine in C# but when I try to run it in VB.NET, I get a NullReferenceException:
Code:
    Private Shared Function PointerToRegistryKey(ByVal hKey As IntPtr, ByVal writable As Boolean, ByVal ownsHandle As Boolean) As RegistryKey
        ' Create a SafeHandles.SafeRegistryHandle from this pointer - this is a private class
        Dim privateConstructors As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic
        Dim safeRegistryHandleType As Type = GetType(Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle")
        Dim safeRegistryHandleConstructorTypes As Type() = {GetType(IntPtr), GetType(System.Boolean)}
        Dim safeRegistryHandleConstructor As ConstructorInfo = safeRegistryHandleType.GetConstructor(privateConstructors, Nothing, safeRegistryHandleConstructorTypes, Nothing)
        Dim safeHandle As Object = safeRegistryHandleConstructor.Invoke(New Object() {hKey, ownsHandle}) ' [b]HERE: safeRegistryHandleConstructor == Nothing[/b]

        ' Create a new Registry key using the private constructor using the safeHandle - this should then behave like a .NET natively opened handle and disposed of correctly
        Dim registryKeyType As Type = GetType(RegistryKey)
        Dim registryKeyConstructorTypes As Type() = {safeRegistryHandleType, GetType(Boolean)}
        Dim registryKeyConstructor As ConstructorInfo = registryKeyType.GetConstructor(privateConstructors, Nothing, registryKeyConstructorTypes, Nothing)
        Dim result As RegistryKey = DirectCast(registryKeyConstructor.Invoke(New Object() {safeHandle, writable}), RegistryKey)
        Return result
    End Function

The only difference between the C# code when it runs is that hKey is over 1500 instead of 932. Everything else matches. Why isn't GetConstructor returning a constructor?
 
I figured it out. GetConstructor (at least in this instance) doesn't work in .NET Framework 4.0. I set it to .NET Framework 3.5 and it worked fine. :D
 
Why was your VB set for .Net Fw 4.0 and not C#? (Since you said it worked in C#)
 
I was converting my code (C# -> VB) for someone else to use. Because I'm using VS2010, it defaulted to 4.0 Client Profile when I created the Visual Basic solution/project. This code will end up in a project coded for .NET Framework 3.5.


FYI, GetConstructor returns null in C# under .NET Framework 4.0 as well. It appears to be a bug in .NET Framework 4.0, not necessarily C# or VB.
 
Microsoft replied with the an answer: .NET 4.0 has native support for RegistryViews negating the need for all that code. That code was broken because the constructors are no longer private, they are public. Examples are on the bug report link.
 
Back
Top