使用自动热键创建没有默认值(非空)的Windows注册表项

使用自动热键创建没有默认值(非空)的Windows注册表项,windows,registry,autohotkey,Windows,Registry,Autohotkey,我需要使用自动热键创建一个具有默认值的新注册表项 简单的解决方案应该是: RegWrite, REG_SZ, HKCU, Environment\testkey 将值名称和值字段保留为空。不幸的是,这会创建一个带有默认值的testkey,即一个空字符串,这不是我想要的。 我想要一个包含未定义内容的默认值,即在RegEdit中创建一个新键时发生的情况(很抱歉,缺少术语,我有一个意大利本地化的操作系统,所以我不知道“not set”值在英语语言环境中是如何显示的) 我找到了一个解决方法,即在创建后

我需要使用自动热键创建一个具有默认值的新注册表项

简单的解决方案应该是:

RegWrite, REG_SZ, HKCU, Environment\testkey
将值名称和值字段保留为空。不幸的是,这会创建一个带有默认值的
testkey
,即一个空字符串,这不是我想要的。 我想要一个包含未定义内容的默认值,即在RegEdit中创建一个新键时发生的情况(很抱歉,缺少术语,我有一个意大利本地化的操作系统,所以我不知道“not set”值在英语语言环境中是如何显示的)

我找到了一个解决方法,即在创建后立即删除默认值,方法是:

RegWrite, REG_SZ, HKCU, Environment\testkey
RegDelete, HKCU, Environment\testkey, AHK_DEFAULT
但这似乎是一个肮脏的黑客行为,如果我必须创建许多这样的密钥,可能会影响性能


是否有一个更清洁的方法来实现同一个目标(也许某种方式来强制<代码> ReaveScript <代码>不创建空白默认值,而只是创建密钥)?

< Po> AutoHykey在ReGrand中构建,正如您所说的,似乎不支持空白键。

我做了一些测试,这里有一些东西供你尝试

如果将ValueName保留为空,则使用子键的默认值;如果省略了sValue,则使用空/零值

#SingleInstance force
RegWrite("REG_SZ","HKCU","Environment\testkey","","")
return

RegWrite(Type, RKey, SKey, ValueName="",sValue="") 
{
    HKCR    := HKEY_CLASSES_ROOT    := 0x80000000   ; http://msdn.microsoft.com/en-us/library/aa393286.aspx 
    HKCU    := HKEY_CURRENT_USER    := 0x80000001 
    HKLM    := HKEY_LOCAL_MACHINE   := 0x80000002 
    HKU     := HKEY_USERS           := 0x80000003 
    HKCC    := HKEY_CURRENT_CONFIG  := 0x80000005 
    HKDD    := HKEY_DYN_DATA        := 0x80000006 
    REG_NONE                := 0                    ; http://msdn.microsoft.com/en-us/library/ms724884.aspx
    REG_SZ                  := 1
    REG_EXPAND_SZ           := 2
    REG_BINARY              := 3
    REG_DW := REG_DWORD     := 4
    REG_DWORD_BIG_ENDIAN    := 5
    REG_LINK                := 6
    REG_MULTI_SZ            := 7
    REG_RESOURCE_LIST       := 8

    if !(RKey := %RKey%)                            ; Dynamicaly assign the RootKey
        Return false                                ; A invalid rootkey was givven
    if !(Type := %Type%)                            ; Dynamicaly assign the DataType
        Return false                                ; A invalid Type was givven
    if DllCall("Advapi32.dll\RegCreateKeyEx","uint", RKey, "Str", SKey, "uint", 0   , "uint", 0 , "uint", 0, "uint",0xF003F, "uint", 0  , "uint *", hKey) { ; create the key
        Return false                                ; Error creating or opening the key 
        }       
    If (Type == REG_SZ or Type == REG_EXPAND_SZ)
                DllCall("Advapi32.dll\RegSetValueEx", "uint", hKey, "str", ValueName, "uint", 0, "uint", Type, "str", sValue, "uint", DataSize := (StrLen(sValue) + 1)*2)   ; write string
   else If (Type == REG_BINARY) {
      size:=StrLen(sValue)//2                       ; set the data to half, one byte=2 hex digits
      VarSetCapacity(Rbin, size,0)                  ; set the capacity
      loop,% size {
         StringLeft, bin, sValue,2                  ; get the left 2digits at the time
         NumPut("0x" Bin,Rbin,A_Index-1,"Char")     ; Store the data
         StringTrimLeft, sValue, sValue, 2          ; remove the to digits
         }
      DllCall("Advapi32.dll\RegSetValueEx","uint",hKey,"str",ValueName,"uint",0,"uint",Type,Uint,&Rbin,"uint",size)   ; write string
    } Else If (Type == REG_DWORD) {
        VarSetCapacity(RDW, 4,0)                    ; setthe capacity to 4 bytes
        NumPut(sValue,RDW,0)                        ; Store the data in itData
        DllCall("Advapi32.dll\RegSetValueEx","uint",hKey,"str",ValueName,"uint",0,"uint",Type,"uint",&RDW,"uint",4)   ; write dword ; a DWORD is a 32-bit (4 byte) number
        ; RDW := "" ; clear the variable
        }
        DllCall("Advapi32.dll\RegCloseKey", "uint", hKey)   ; Release the handle of the key
    return, true
}
我在win 7 64位上使用来自的ahk 1.1.16.05 32位unicode


这在我的测试中至少起到了作用,我认为您正在尝试做的事情。

也许我应该提到,我需要一个适用于WindowsXP和Windows7的解决方案,尽管这些信息可能不太相关。+1对于真正的努力,但我不会接受它,因为它确实不能回答我的问题。虽然这是一个解决方案,但我要求一个比我的更干净的解决方案(而且可能更有效)。您可以使用
DllCall
调用Win32 API,从我的观点和用例来看,这比像我一样调用
RegDelete
要困难得多。此外,我还担心它的性能可能会更差,因为它涉及到所有黑客
DllCall
所做的工作,以建立一个合适的堆栈框架来调用底层的C API函数(您的解决方案涉及三个重
DllCall
s,而不仅仅是我的两个“常规”函数调用)。好的!但是使用dllcall决不是黑客行为,它与使用内置函数一样,只是具有更多的控制。我不能分辨DLLASK是不是重量级,那么函数调用,因为我没有在C++源代码中查找它们,但是我真的怀疑它。HMM我只是查了一下,在源代码中使用了3个调用,这里是为了你的自公平点,我应该把HOK引用进去。我的意思是“不干净”。至于DLCALL的“重量级”,即使我没有看它的C++实现,它也是一个FFI(FieldFieldFieldOffice)工具:要执行一个调用,必须指定C++类型作为字符串参数,所有这些信息必须转化为C++中可以调用的东西,但是C++函数原型不能在运行时合成。因此,这可能涉及到相当恶劣的引擎盖下黑客。我见过的每一个FFI库(例如libffi、Cinvoke、LuaJIT FFI)都使用assembly。我真的不太了解dllcall的工作原理。我可以说,我当时还不知道更干净的方法:),但我很乐意尝试