Read and Write registry entry of type REG_MULTI_SZ using Delphi

 ̄綄美尐妖づ 提交于 2020-04-08 18:31:06

问题


Delphi offers the library System.Win.Registry to manipulate the windows registry. Unfortunately it doesn't contain read/write procedures for the registry datatype REG_MULTI_SZ (=list of strings).

The following code returns an ERegistryException with "invalid datatype" - it seems only to work with datatype REG_SZ:

  Registry := TRegistry.Create;
  Registry.RootKey := HKEY_LOCAL_MACHINE;
  Registry.OpenKey(cKey, false);
  sValue := Registry.ReadString('MyRegEntry');

Meanwhile I am able to read the REG_MULTI_SZ value with

  Registry.ReadBinaryData('MyRegEntry', pBuf, sizeof(pBuf));

but if I write it back using WriteBinaryData() it will be written to the registry as datatype REG_BINARY instead of REG_MULTI_SZ. So that's not working properly.

How can I manipulate registry data of datatype REG_MULTI_SZ using Delphi?


回答1:


I have written two functions (a class helper) to extend the functionality of TRegistry:

unit Common.RegistryHelper;

interface

uses
  System.Classes, System.Win.Registry, Winapi.Windows, System.Math;

type
  TRegistryHelper = class helper for TRegistry
  public
    function ReadMultiSz(const name: string; var Strings: TStrings): boolean;
    function WriteMultiSz(const name: string; const value: TStrings): boolean;
  end;

implementation

function TRegistryHelper.ReadMultiSz(const name: string; var Strings: TStrings): boolean;
var
  iSizeInByte: integer;
  Buffer: array of WChar;
  iWCharsInBuffer: integer;
  z: integer;
  sString: string;
begin
  iSizeInByte := GetDataSize(name);
  if iSizeInByte > 0 then begin
    SetLength(Buffer, Floor(iSizeInByte / sizeof(WChar)));
    iWCharsInBuffer := Floor(ReadBinaryData(name, Buffer[0],
      iSizeInByte) / sizeof(WChar));
    sString := '';
    for z := 0 to iWCharsInBuffer do begin
      if Buffer[z] <> #0 then begin
        sString := sString + Buffer[z];
      end else begin
        if sString <> '' then begin
          Strings.Append(sString);
          sString := '';
        end;
      end;
    end;
    result := true;
  end else begin
    result := false;
  end;
end;

function TRegistryHelper.WriteMultiSz(const name: string; const value: TStrings): boolean;
var
  sContent: string;
  x: integer;
begin
  sContent := '';
  for x := 0 to pred(value.Count) do begin
    sContent := sContent + value.Strings[x] + #0;
  end;
  sContent := sContent + #0;
  result := RegSetValueEx(CurrentKey, pchar(name), 0, REG_MULTI_SZ,
    pointer(sContent), Length(sContent)*sizeof(Char)) = 0;
end;

end.

Using the functions above you can simply write in your program the following code to add a value to a REG_MULTI_SZ entry:

procedure AddValueToRegistry();
const
  cKey = '\SYSTEM\ControlSet001\services\TcSysSrv';
var
  Registry: TRegistry;
  MyList: TStrings;
begin
  Registry := TRegistry.Create;
  Registry.RootKey := HKEY_LOCAL_MACHINE;
  Registry.OpenKey(cKey, false);
  try
    MyList := TStringList.Create();
    Registry.ReadMultiSz('MyRegEntry', MyList);
    MyList.Add('NewEntry');
    Registry.WriteMultiSz('MyRegEntry', MyList);
  finally
    MyList.Free;
  end;
  Registry.Free;
end;


来源:https://stackoverflow.com/questions/48826844/read-and-write-registry-entry-of-type-reg-multi-sz-using-delphi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!