2014-11-16 31 views
2

我需要创建没有默认值使用AutoHotkey的一个新的注册表键的默认值(不为空)一个Windows注册表项。创建使用AutoHotkey的

琐碎的解决方案应该是:

RegWrite, REG_SZ, HKCU, Environment\testkey 

离开值名称和值字段为空。不幸的是,这产生了testkey空白默认值,即一个空字符串,这不是我想要的。 我想要一个默认值undefined内容,也就是当我在RegEdit中创建一个新密钥时发生的相同情况(抱歉,由于缺乏术语,我有一个意大利本地化的操作系统,所以我不知道如何“不”设置“值以英文语言环境显示)。

我发现了一个解决办法,这仅仅是与创建后删除默认值:

RegWrite, REG_SZ, HKCU, Environment\testkey 
RegDelete, HKCU, Environment\testkey, AHK_DEFAULT 

,但它似乎是一个肮脏的黑客,也许如果我不得不创造出许多这样的键会影响性能。

是否有更简洁的方式来实现相同的目标(也许某种方式强制RegWrite不创建空白默认值,而只是创建密钥)?

+0

也许我应该提到,我需要一个适用于WindowsXP和Windows7的解决方案,虽然这些信息可能并不相关。 –

回答

3

Autohotkeys内置的regwrite按照你所说的做,似乎不支持空白键。

我做了一个小测试,这里是东西给你尝试

如果离开ValueName的空白子项的默认值时,如果S值省略空白/零值被使用。

#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 
} 

我就赢7 64位用AHK 1.1.16.05 32位的unicode从http://ahkscript.org

这工作在我的测试ATLEAST什么,我认为你正在尝试做的。

+0

+1为真正的努力,但我不会接受它,因为它真的不回答我的问题。尽管这是一个解决方案,但我要求一个比我更清洁的***解决方案(可能更有效)。你使用'DllCall'调用Win32 API,从我的POV和用例来看,这比调用'RegDelete'更像一个黑客。此外,我担心它的性能可能会更糟糕,因为它涉及到所有的嘲讽'DllCall'确实构建了一个合适的堆栈框架来调用底层的C API函数(您的解决方案涉及三个沉重的'DllCall's而不仅仅是我的两个“常规“函数调用)。 –

+0

好吧!但使用dllcall绝不是骇人听闻的,它与使用内置函数一样,只是更多的控制。而且我不能说dllcalls是否重载了函数调用,因为我没有在C++源代码中查找它们,但我真的怀疑它。 – blackholyman

+0

嗯我只是看了起来,同样的3来电在这里看到你的自我https://github.com/Lexikos/AutoHotkey_L/blob/master/source/script_registry.cpp#L353 – blackholyman