I have a function (credit to @Charlieface) that opens a registry symlink and returns a RegistryKey
handle:
public static RegistryKey OpenSubKeySymLink(this RegistryKey key, string name, RegistryRights rights = RegistryRights.ReadKey, RegistryView view = 0)
{
var error = RegOpenKeyExW(key.Handle, name, REG_OPTION_OPEN_LINK, ((int)rights) | ((int)view), out var subKey);
if (error != 0)
{
subKey.Dispose();
throw new Win32Exception(error);
}
return RegistryKey.FromHandle(subKey); // RegistryKey will dispose subKey
}
I want to delete this registry symlink by using the return handle of the key.
The functions that allows me to delete Registry keys require to provide the name of the key as a string, but in my case this is a symlink, it is not enough.
I have the RegistryKey
handle as object and I want to delete it.
I tried to delete it like that but it doesn't accept it:
[DllImport("advapi32.dll", EntryPoint = "RegDeleteKeyEx", SetLastError = true)]
public static extern int RegDeleteKeyEx(
UIntPtr hKey,
string lpSubKey,
uint samDesired, // see Notes below
uint Reserved);
static void Main(string[] args)
{
RegistryKey key;
key = OpenSubKeySymLink(Microsoft.Win32.Registry.CurrentUser, @"SOFTWARE\Microsoft\Windows\ABC", RegistryRights.ReadKey, 0);
RegDeleteKeyEx(key, @"SOFTWARE\Microsoft\Windows\ABC", 0x100, 0); // don't know how to delete the RegistryKey handle
}
When I type key.
I see that it as functions for deletion but it again asks for the key path as a string.
Undocumented but calling RegDeleteKey(hKey, @"")
(advapi32) will delete a key by handle (works all the way back to Win95/NT4).
I don't know what the behavior on symlinks is. It most likely deletes the link (if you specifically opened the symlink) and not the target but you just have to check to be sure.
If you don't want to rely on undocumented behavior you have to call ZwDeleteKey
(ntdll) as suggested by RbMm.