簡體   English   中英

注冊表 - 如何使用 C++ 重命名注冊表中的鍵?

[英]Registry - How to rename key in registry using C++?

如何使用 C++ 重命名注冊表中的鍵?

我想將鍵“Myapp\Version1”重命名為“Myapp\Version2”。

我在 MSDN 中沒有看到任何關於重命名注冊表項的功能。

如果您的應用需要 Vista 或更新版本的 Windows,您可以使用RegCopyTree () 后跟RegDeleteTree ()。

在舊版本的 Windows 上沒有重命名功能,您需要在自己的 AFAIK 上復制/刪除。

關於這個舊條目的更多信息:

NTRenameKey()是用於重命名注冊表項的舊 API。

此外, Pavel有更多關於 randomsock 的答案中提到的 RegRenameKey() 調用的信息,並且(盡管這是一個 C++ 問題)為它提供了這個很好的 PInvoke 簽名。

[DllImport("advapi32")]
public static extern int RegRenameKey(
     SafeRegistryHandle hKey,
     [MarshalAs(UnmanagedType.LPWStr)] string oldname,
     [MarshalAs(UnmanagedType.LPWStr)] string newname);

如果有人需要有關重命名的詳細信息,我會在此處留下日志。

未記錄的RegRenameKey顯然是定義的:

LSTATUS WINAPI RegRenameKey( 
  _In_         HKEY    hKey, 
  _In_         LPCTSTR lpSubKeyName,
  _In_         LPCTSTR lpNewKeyName 
);

甚至有一個問題。 第一個lpSubKeyName帶有 path 的鍵 但是, lpNewKeyName只是一個沒有 path 的新名稱

編輯 24.06.22022:

顯然,經過多年的努力,Microsoft 最終決定將此功能記錄在案是一個好主意。 您可以找到文檔: RegRenameKey function (注意到它的 Dirk Vollmar 的禮貌)

如果您需要支持 XP,可以使用SHCopyKey后跟RegDeleteKeyEx

我知道這是一個舊條目,但萬一其他人來看,像我一樣......

這個 MSDN page中,有人發現了一個未記錄的RegRenameKey(hKey, keyName, newKeyName)從 Vista 開始可用。

祝我的程序員同胞們,

以防萬一您嘗試在 C# (P/INVOKE) 中執行此操作,我是這樣做的:

    public static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));

    [Flags]
    public enum ACCESS_MASK : uint
    {
        DELETE = 0x00010000,
        READ_CONTROL = 0x00020000,
        WRITE_DAC = 0x00040000,
        WRITE_OWNER = 0x00080000,
        SYNCHRONIZE = 0x00100000,
        STANDARD_RIGHTS_REQUIRED = 0x000F0000,
        STANDARD_RIGHTS_READ = 0x00020000,
        STANDARD_RIGHTS_WRITE = 0x00020000,
        STANDARD_RIGHTS_EXECUTE = 0x00020000,
        STANDARD_RIGHTS_ALL = 0x001F0000,
        SPECIFIC_RIGHTS_ALL = 0x0000FFFF,
        ACCESS_SYSTEM_SECURITY = 0x01000000,
        MAXIMUM_ALLOWED = 0x02000000,
        GENERIC_READ = 0x80000000,
        GENERIC_WRITE = 0x40000000,
        GENERIC_EXECUTE = 0x20000000,
        GENERIC_ALL = 0x10000000
    }

    [Flags]
    public enum REGSAM : uint
    {
        DELETE = 0x00010000,
        READ_CONTROL = 0x00020000,
        WRITE_DAC = 0x00040000,
        WRITE_OWNER = 0x00080000,
        KEY_QUERY_VALUE = 0x0001,
        KEY_SET_VALUE = 0x0002,
        KEY_CREATE_SUB_KEY = 0x0004,
        KEY_ENUMERATE_SUB_KEYS = 0x0008,
        KEY_NOTIFY = 0x0010,
        KEY_CREATE_LINK = 0x0020,
        KEY_WOW64_32KEY = 0x0200,
        KEY_WOW64_64KEY = 0x0100,
        KEY_WOW64_RES = 0x0300,
        KEY_READ = (ACCESS_MASK.STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~ACCESS_MASK.SYNCHRONIZE),
        KEY_WRITE = (ACCESS_MASK.STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~ACCESS_MASK.SYNCHRONIZE),
        KEY_EXECUTE = (KEY_READ) & (~ACCESS_MASK.SYNCHRONIZE),
        KEY_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~ACCESS_MASK.SYNCHRONIZE),
    }

    [DllImport("advapi32.dll", SetLastError = true)]
    static extern int RegCloseKey(
        IntPtr hKey);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    public static extern int RegOpenKeyEx(
        IntPtr hKey,
        string subKey,
        uint ulOptions,
        REGSAM samDesired,
        out IntPtr hkResult);

    [DllImport("ntdll.dll")]
    static extern int NtRenameKey(
        IntPtr KeyHandle,
        ref UNICODE_STRING NewName);

    [StructLayout(LayoutKind.Sequential)]
    private struct UNICODE_STRING
    {
        public ushort Length;
        public ushort MaximumLength;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string Buffer;

        public UNICODE_STRING(string value)
        {
            int len = value.Length;
            Length = (ushort) (2 * len);
            MaximumLength = (ushort) (2 * (len + 1));
            Buffer = value;
        }
    }

    public static bool RenameHklmKey(string key, string newName)
    {
        IntPtr keyHandle;
        UNICODE_STRING unicodeString = new UNICODE_STRING(newName);
        int result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, REGSAM.KEY_ALL_ACCESS, out keyHandle);
        if (0 == result)
        {
            result = NtRenameKey(keyHandle, ref unicodeString);
            RegCloseKey(keyHandle);
        }

        return 0 == result;
    }

枚舉取自Vanara 項目希望它可以幫助某人

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM