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

RegSetValueEx (advapi32)
 
.
Summary
Sets the data and type of a specified value under a registry key.

C# Signature:

[DllImport("advapi32.dll", SetLastError = true)]
static extern int RegSetValueEx(
    IntPtr hKey,
    [MarshalAs(UnmanagedType.LPStr)] string lpValueName,
    int Reserved,
    Microsoft.Win32.RegistryValueKind dwType,
    [MarshalAs(UnmanagedType.LPStr)] string lpData,
    int cbData);

// Alternate definition - more correct
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint RegSetValueEx(
     UIntPtr hKey,
     [MarshalAs(UnmanagedType.LPStr)]
     string lpValueName,
     int Reserved,
     RegistryValueKind dwType,
     IntPtr lpData,
     int cbData);

VB Signature:

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

Declare Auto Function RegSetValueEx Lib "advapi32.dll" (
   ByVal hKey As IntPtr,
   ByVal lpValueName As String,
   ByVal Reserved As Integer,
   ByVal dwType As Integer,
   ByVal lpData As IntPtr,
   ByVal cbData As Integer
) As Integer

Alternative Managed API:

My.Computer.Registry.SetValue(KeyName, valueName, value, valueKind)
with signature:
   keyName As String
   valueName As String
   value As Object
   valueKind as RegistryValueKind

If you are getting an HKEY from some source without a managed equivalent, it converts to a .NET RegistryKey as:

IntPtr hKey = /* unmanaged function */
RegistryKey regKey = RegistryKey.FromHandle(new SafeRegistryHandle(hKey, true));

Provided you specify true in the SafeRegistryHandle constructor, there is then no need to call RegCloseKey either.

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

' Overloaded, see below
Public Sub SetValue(ByVal Name As String, ByVal Value As Object)
   SetValue(Name, Value, RegistryValueKind.Unknown)
End Sub

' Write a value to a key
Public Sub SetValue(ByVal Name As String, ByVal Value As Object, ByVal RegType As RegistryValueKind)
   Dim gch As GCHandle
   Dim ptr As IntPtr
   Dim ret, Size As Integer

   ' So we have to figure out the type
   If RegType = RegistryValueKind.Unknown Then
     Select Case Value.GetType.ToString
       Case "System.String"
     RegType = RegistryValueKind.String
       Case "System.Int32"
     RegType = RegistryValueKind.DWord
       Case "System.Int64"
     RegType = RegistryValueKind.QWord
       Case "System.String[]"
     RegType = RegistryValueKind.MultiString
       Case "System.Byte[]"
     RegType = RegistryValueKind.Binary
       Case Else
     ' convert it to a string
     RegType = RegistryValueKind.String
     Value = Value.ToString
     End Select
   End If

   Select Case RegType
     Case RegistryValueKind.Binary
       Dim temp() As Byte
       temp = DirectCast(Value, System.Byte())
       Size = temp.Length
       gch = GCHandle.Alloc(temp, GCHandleType.Pinned)
       ptr = Marshal.UnsafeAddrOfPinnedArrayElement(temp, 0)
     Case RegistryValueKind.DWord
       Dim temp As Integer = CInt(Value)
       Size = 4
       ptr = Marshal.AllocHGlobal(Size)
       Marshal.WriteInt32(ptr, 0, temp)
     Case RegistryValueKind.ExpandString
       Dim temp As String = CStr(Value)
       Size = (temp.Length + 1) * Marshal.SystemDefaultCharSize
       ptr = Marshal.StringToHGlobalAuto(temp)
     Case RegistryValueKind.MultiString
       Dim temp, lines() As String
       Dim index As Integer
       lines = DirectCast(Value, System.String())

       ' Calculate the total size, including the terminating null
       Size = 0
       For Each temp In lines
         Size += (temp.Length + 1) * Marshal.SystemDefaultCharSize
       Next
       Size += Marshal.SystemDefaultCharSize
       ptr = Marshal.AllocHGlobal(Size)

       index = 0
       For Each temp In lines
         Dim tempPtr As IntPtr
         Dim tempArray() As Char

         tempArray = temp.ToCharArray
         tempPtr = New IntPtr(ptr.ToInt64 + index)
         Marshal.Copy(tempArray, 0, tempPtr, tempArray.Length)
         index += (tempArray.Length + 1) * Marshal.SystemDefaultCharSize
       Next
     Case RegistryValueKind.QWord
       Dim temp As Long = CLng(Value)
       Size = 8
       ptr = Marshal.AllocHGlobal(Size)
       Marshal.WriteInt64(ptr, 0, temp)
     Case RegistryValueKind.String
       Dim temp As String = CStr(Value)
       Size = (temp.Length + 1) * Marshal.SystemDefaultCharSize
       ptr = Marshal.StringToHGlobalAuto(temp)
     Case Else
       Throw New ApplicationException("Registry type of " & RegType & " is not supported")
   End Select

   ' let's do it!
   ret = RegSetValueEx(hKey, Name, 0, RegType, ptr, Size)
   If ret <> 0 Then
     Throw New Win32Exception(ret)
   End If

   ' clean up
   If gch.IsAllocated Then
     gch.Free()
   Else
     Marshal.FreeHGlobal(ptr)
   End If
End Sub

C# alternate defintion example

    public bool SetNamedValue(string valName, object value, RegistryValueKind type)
    {
        UIntPtr hKey = UIntPtr.Zero;

        try
        {
        uint retVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryPath, 0, WRITE_FLAG_MASK, out hKey);
        if (retVal == 0)
        {
            int size = 0;
            IntPtr pData = IntPtr.Zero;
            switch (type)
            {
            case RegistryValueKind.String:
                size = ((string)value).Length + 1;
                pData = Marshal.StringToHGlobalAnsi((string)value);
                break;
            case RegistryValueKind.DWord:
                size = Marshal.SizeOf(typeof(Int32));
                pData = Marshal.AllocHGlobal(size);
                Marshal.WriteInt32(pData, (int)value);
                break;
            case RegistryValueKind.QWord:
                size = Marshal.SizeOf(typeof(Int64));
                pData = Marshal.AllocHGlobal(size);
                Marshal.WriteInt64(pData, (long)value);
                break;
            }

            // Set the value
            retVal = RegSetValueEx(hKey, valName, 0, type, pData, size);
            if (retVal != 0)
            {
            Logger.WriteLog("Error writing value to '{0}\\{1}: 0x{2:x}, return code: {3}", registryPath, valName, Marshal.GetLastWin32Error(), retVal);
            return false;
            }
        }
        else
        {
            Logger.WriteLog("Error opening registry key HKLM\\{0}: {1:x}, return code: {2}", registryPath, Marshal.GetLastWin32Error(), retVal);
            return false;
        }
        }
        finally
        {
        if (hKey != UIntPtr.Zero)
        {
            RegCloseKey(hKey);
        }
        }

        return true;
    }

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