Multi String Registry Type

How can I retrieve a multi-string value from the registry?
LlysanderAsked:
Who is Participating?
 
philipleighsConnect With a Mentor Commented:
See my comment above.

Cheers,
Phil.

0
 
bruintjeCommented:
Hi Llysander,

You can use the GetValues property of a TRefistry object, as it will return a stringlist containing all the datavalues of a key currently selected.

Bruintje.
0
 
BlackDeathCommented:
if you're using delphi 2 upwards, that is...

Black Death
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
LlysanderAuthor Commented:
There does not appear to be a GetValues property in TRegistry in Delphi 4.
0
 
philipleighsCommented:
In D4, it's called GetValueNames
0
 
LlysanderAuthor Commented:
GetValueNames just gives me a list of the Value names.  I need to be able to retrieve the value data.  I can do that for most data types, but not multi strings.
0
 
rwilson032697Commented:
Use ReadBinaryData to read the block of data from the registry into a memory block. If this multi string object is essentially an in memory representation of a structure then read it straight into the structure, otherwise you will need to parse it yourself by looking at the length byte and copying the following n bytes into individual strings.

To read it into a structure do this:

TheRegistry.ReadBinaryData('TheKey', TheStructure, sizeof(TheStructure));


Cheers,

Raymond.
0
 
LlysanderAuthor Commented:
I've tried using a ReadBinary to get the data.  It generates an exception, 'Invalid Data Type';  None of the read methods seem to work either.  I cannot find any registry components that deal with it either, at least ones that don't cost a couple hundred dollars.
0
 
LlysanderAuthor Commented:
Further information on the question:
Delphi 4.02 attempting to retrive the valuedata from the following key.
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System
ValueName = SystemBiosVersion
DataType = REG_MULTI_SZ

0
 
bruintjeCommented:
Hi again,

I've build a little project showing a few things in the registry, it's about 6K so I could email it to you.
It will read keys, values and show data types etc.I'm not certain what you mean bij multistrings but I gues subkeys and their values.

So let me know if you're interested.

Bruintje.
0
 
philipleighsCommented:
A multi string is a chunk of memory where each string is separated by a NULL, and where the whole thing is doubly NULL terminated.

Here is what you want. The function GetMultiStringFromReg fills a string list with the strings, or returns false (or raises exception) otherwise.
It is not the most elegant solution by replacing #0 with #1, but this just makes life easier (can use Pos). StrPas of course treats #0 specially.

It should copy, paste and compile.

procedure MultiStringToStringList(Multi: string; List: TStringList);
  var s: string;
  begin
    while Pos(#1, Multi) > 0 do
      begin
        s := Copy(Multi, 1, Pos(#1, Multi) - 1);
        if s <> '' then
          List.Add(s);
        Delete(Multi, 1, Pos(#1, Multi));
      end;
  end;

function GetMultiStringFromReg(RegPath, RegKey: string; s: TStringList): Boolean;
  var Reg: TRegistry;
      Size: Integer;
      P: PChar;
      DataType: TRegDataType;
      Count: Integer;
begin
  Result := false;
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey(RegPath, false) then
      begin
        Size := Reg.GetDataSize(RegKey);
        if Size <> -1 then
          begin
            GetMem(P, Size);
            //Originally used ReadBinaryData but got nasty error
            //Use RegQueryValueEx instead
            DataType := rdBinary;
            RegQueryValueEx(Reg.CurrentKey, PChar(RegKey), nil, @DataType, PByte(P), @Size);
            for Count := 0 to Size - 1 do
              if (P + Count)^ = #0 then
                (P + Count)^ := #1;
            MultiStringToStringList(StrPas(P), s);
            FreeMem(P);
            Result := true;
          end;
        Reg.CloseKey;
      end;
  finally
    Reg.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
  var Strings: TStringList;
      Count: Integer;
begin
  Strings := TStringList.Create;
  if GetMultiStringFromReg('Hardware\Description\System', 'SystemBiosVersion', Strings) then
    for Count := 0 to Strings.Count - 1 do
      ShowMessage(Strings[Count]);
end;


0
 
LlysanderAuthor Commented:
Testing Philipleighs example.
Did a quick eye scan through the code, looks good, havn't had a chance to implement it yet.

Philip, if you would please post it as an answer so I can get it off the waiting answer list.
0
 
bruintjeCommented:
Oke looks good, but I've implemented this with the valuenames in the project I talked about. It loads all the subkey values into a listbox. So if you would still take a look at it let me know.

Greetz
Bruintje
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.