Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

RegQueryValueEx (advapi32)
 
.
Summary
Retrieves the type and data for a specified value name associated with an open registry key.

C# Signature:

// This signature will not get an entire REG_BINARY value. It will stop at the first null byte.
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]
static extern int RegQueryValueEx(
    UIntPtr hKey,
    string lpValueName,
    int lpReserved,
    out uint lpType,
    System.Text.StringBuilder lpData,
    ref uint lpcbData);

// Alternate definition - more correct
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint RegQueryValueEx(
    UIntPtr hKey,
    string lpValueName,
    int lpReserved,
    ref RegistryValueKind lpType,
    IntPtr lpData,
    ref int lpcbData);

VB Signature:

Flavor 1: (For strings)
<System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError:=True)> _
Friend Shared Function RegQueryValueEx( _
    ByVal hKey As IntPtr, _
    ByVal lpValueName As String, _
    ByVal lpReserved As Integer, _
    ByRef lpType As Integer, _
    ByVal lpData As System.Text.StringBuilder, _
    ByRef lpcbData As Integer) As Integer
End Function

Flavor 2: (For binary)
<System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError:=True)> _
Friend Shared Function RegQueryValueEx( _
    ByVal hKey As IntPtr, _
    ByVal lpValueName As String, _
    ByVal lpReserved As Integer, _
    ByRef lpType As Integer, _
    ByVal lpData As byte(), _
    ByRef lpcbData As Integer) As Integer
End Function

Key Types:
Type Value
REG_NONE 0
REG_SZ 1
REG_EXPAND_SZ 2
REG_BINARY 3
REG_DWORD 4
REG_DWORD_LITTLE_ENDIAN 4
REG_DWORD_BIG_ENDIAN 5
REG_LINK 6
REG_MULTI_SZ 7

User-Defined Types:

None.

Notes:

Managed APIs won't let you get raw REG_EXPAND_SZ values. You'll be forced to use Win32 APIs for this. Also, since .NET won't give access to the key pointer (hKey), you'll have to browse the registry using pInvoke or use Reflection to query the private member (see sample code for how to).

If you don't need the key type, set it to null

If you don't need data, set both lpData and lpcbData to null

If you only need value size, set lpcbData to null

Tips & Tricks:

None.

Sample Code:

'Allows to read System Environment Path and keeps it unexpanded (in opposition to default .NET behavior)
Dim environmentReg As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Control\Session Manager\Environment", True)

'Retrieves the hKey "field"
Dim environmentRegHKey As System.Reflection.FieldInfo = environmentReg.GetType.GetFields(Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)(0)

'Get the instance value back to intPtr
Dim ParentKey As IntPtr = DirectCast(environmentRegHKey.GetValue(environmentReg), IntPtr)

'An alternative to this section would be to call RegOpenKeyEx and convert value to intPtr:
'Dim subKey As Integer
'RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", 0, KEY_SET_VALUE Or KEY_ENUMERATE_SUB_KEYS, subKey)
'Dim ParentKey As IntPtr = new IntPtr(subKey)
'In fact, you could probably even set the output as intPtr already but I didn't test it.


Dim KeyType As Integer 'replace by nothing if you don't need the info
Dim KeyValue As System.Text.StringBuilder
Dim KeyByteValue As Byte()
Dim KeyValueLength As Integer

'First, retrieve buffer size
Dim queryValueReturn As Integer = RegQueryValueEx(ParentKey, "path", Nothing, KeyType, Nothing, KeyValueLength)

'If there is no error
'(if you have an error and you want to know the description, you could call environmentReg's private method GetMessage)
If queryValueReturn = 0 Then
    'Init buffer
    KeyValue = New System.Text.StringBuilder(KeyValueLength)
    ReDim KeyByteValue(KeyValueLength - 1)

    queryValueReturn = RegQueryValueEx(ParentKey, "path", Nothing, KeyType, KeyValue, KeyValueLength)
    queryValueReturn = RegQueryValueEx(ParentKey, "path", Nothing, KeyType, KeyByteValue, KeyValueLength)

    'You should verify the operation succeeded before continuing by validating queryValueReturn

    'Don't forget to close the key ressource
    environmentReg.Close()
End If

C#

    uint pvSize = 1024;
    System.Text.StringBuilder pvData = new System.Text.StringBuilder(1024);
    uint pdwType = 0;
    int success = RegQueryValueEx(regKey, "AKeyName", 0, out pdwType, pvData, ref pvSize);

Sample Code (C#) to read a string value

string example = ReadRegKey(HKEY_LOCAL_MACHINE, @"Software\SomeCompany\OurProduct", "InstalledVersion");

private static string ReadRegKey(UIntPtr rootKey, string keyPath, string valueName)
{
   if (RegOpenKeyEx(rootKey, keyPath, 0, KEY_READ, out hKey) == 0)
   {
      uint size = 1024;
      uint type;
      string keyValue = null;
      StringBuilder keyBuffer = new StringBuilder();

      if (RegQueryValueEx(hKey, valueName, IntPtr.Zero, out type, keyBuffer, ref size) == 0)
      keyValue = keyBuffer.ToString();

      RegCloseKey(hKey);

      return(keyValue);
  }

  return(null);  // Return null if the value could not be read

}

C# alternate defintion example

    Don't forget to add this constant!
    public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);

    public object GetNamedValue(string valName)
    {
        UIntPtr hKey = UIntPtr.Zero;
        IntPtr pResult = IntPtr.Zero;

        try
        {
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryPath, 0, READ_FLAG_MASK, out hKey) == 0)
        {
            int size = 0;
            RegistryValueKind type = RegistryValueKind.Unknown;

            // Get the size of buffer we will need
            uint retVal = RegQueryValueEx(hKey, valName, 0, ref type, IntPtr.Zero, ref size);
            if (size == 0)
            {
            return null;
            }

            pResult = Marshal.AllocHGlobal(size);

            retVal = RegQueryValueEx(hKey, valName, 0, ref type, pResult, ref size);
            if (retVal != 0)
            {
            Logger.WriteLog("Error querying value '{0}\\{1}: 0x{2:x}, return code: {3}", registryPath, valName, Marshal.GetLastWin32Error(), retVal);
            }
            else
            {
            switch (type)
            {
                case RegistryValueKind.String:
                return Marshal.PtrToStringAnsi(pResult);
                case RegistryValueKind.DWord:
                return Marshal.ReadInt32(pResult);
                case RegistryValueKind.QWord:
                return Marshal.ReadInt64(pResult);
            }
            }
        }
        else
        {
            Logger.WriteLog("Error opening registry key HKLM\\{0}: {1:x}", registryPath, Marshal.GetLastWin32Error());
        }
        }
        finally
        {
        if (hKey != UIntPtr.Zero)
        {
            RegCloseKey(hKey);
        }

        if (pResult != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(pResult);
        }
        }

        return null;
    }

Alternative Managed API:

namespace Microsoft.Win32;

classes Registery, RegistryKey

Documentation

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version
Revisions