[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);
<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
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.
None.
Please add some!
' 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
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;
}