Which registry value types do I have to trim the null from? Thanks
Printable View
Which registry value types do I have to trim the null from? Thanks
If you're using RegQueryValueEx, (from MSDN)You should test for a null before trying to remove it, as it may not actually be there - it depends on the OS, amongst other things. RegQueryValueEx can return erroneous results if the data was incorrectly written to the registry.Quote:
If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, then lpcbData will also include the size of the terminating null character.
If you're using SHQueryValueEx, you don't need to do anything as it applies post-processing to remove a null automatically. I'm fairly sure the same applies to WMI and WSH.
Okay, thanks. What would be a good short code to read a value if I have no idea what type it is? Thanks
Good question. There isn't one :) . You have to test for every type then call the routine to extract that type. For instance, REG_BINARY and REG_NONE are usually (but not always) associated with UDTs, so unless you know the UDT structure, the results could be a mess.Quote:
Originally Posted by abazabam
There are at least 7 different types, and at least 11 different ways of reading values using just the "Regxxxxxxxxxxxxx" APIs alone. The way you call "RegQueryValueEx" can be slightly different depending on the type you are trying to extract and the way it was written.
Then of course there's the "SHRegxxxxxxxxxx" APIs, WMI, WSH.
You'll have to be more specific on the method (API, WMI etc) you want to use first :)
I'm especially having trouble with the null trimmiing thing. So from the quote above means that I only have to trim the null from REG_SZ, REG_MULTI_SZ and REG_EXPAND_SZ types? Do they always have nulls? And what about the value name? Do I always have to trim the null from the value name? Earlier, I was being stupid and I was trying to trim the null from a binary value but every other character was hex 00 (which is a null?) so it was cut off after the first character. Thanks
You only have to trim the last null from REG_SZ, REG_MULTI_SZ and REG_EXPAND_SZ types. (For the benefit of other readers, a NULL is Chr(0) or vbNullChar - not to be confused with vbNullString or vbNull). And yes, they always have nulls (00) as the last character - if written correctly. The reason I say "if written correctly" is because I've seen an obscure article which says it's possible to write it incorrectly (and I know how), but that's another story.
To handle the last null:
vb Code:
If Right$(strRet, 1) = Chr(0) Then 'or vbNullChar strRet = Left$(strRet, (Len(strRet)) - 1) End If
REG_MULTI_SZ types use a null as a string seperator (if it's written correctly ;) ), as well as a character seperator, so if you have 2 strings - "I like beer" & "Please do not smoke" - each character will be seperated by a null, as will the strings, so between the "r" in "beer" and the "P" in "Please", there will be 3 nulls. The API handles the character seperator nulls, but you have to handle the string seperator null and the last null yourself. For example, to seperate the strings you could do:vb Code:
Replace(strRet, Chr(0), vbCrLf) 'or vbNullChar
The good news is you don't have to touch the value names :)
Okay because Arkadiy Olovyannikov's registry searcher (http://freevbcode.com/source/Search_Registry.zip) has:
ValueName = TrimNull(ValueName)
Oops, my bad. Yes you do need to trim the last null from the value name:
If you're displaying it in a vb control (textbox etc), vb will discard the null, but it's probably wiser to remove it yourself.Quote:
From MSDN - RegEnumKey:
lpName - [out] Pointer to a buffer that receives the name of the subkey, including the terminating null character. This function copies only the name of the subkey, not the full key hierarchy, to the buffer.
I've just tried out Arkadiy Olovyannikov's app, and it looks like the "TrimNull" sub is flawed - it discards any data after the FIRST null instead of simply removing the LAST null. Assuming that a REG_MULTI_SZ value has been correctly written using nulls as string seperators, any strings after the first null will not be displayed. :(
Okay, I'll use your code instead. I think I have it all figured out but I just need to do a little more testing. Thank you!
We've exchanged a few PM's about this, so I decided to create a little project to demo various aspects of writing/reading SZ and MULTI_SZ values.
1) How to differentiate "(Default) value not set" from an empty "(Default)" value (where the value name has been initialised) and from a "(Default)" value that contains nulls.
2) Writing, and in particular, reading REG_MULTI_SZ values correctly.