1

I have tried to get my SQLServer instances names from the registry by using this code:

type
  TRegistryHelper = class helper for TRegistry
  public
    function ReadMultiSz(const name: string; var Strings: TStrings): boolean;
  end;
    
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;

procedure TForm1.Button1Click(Sender: TObject);
const
  cKey = '\SOFTWARE\Microsoft\Microsoft SQL Server';
var
  Registry: TRegistry;
  MyList: TStrings;
begin
  Registry := TRegistry.Create;
  Registry.RootKey := HKEY_LOCAL_MACHINE;
  if Registry.OpenKeyReadOnly(cKey) then
  try
    MyList := TStringList.Create();
    Registry.ReadMultiSz('InstalledInstances', MyList);
    ListBox1.Items.Assign(MyList);
  finally
    MyList.Free;
  end;
  Registry.Free;
end;

But I have noted the iSizeInByte = -1 every time, and I failed to get those names by this way.

Also, I have noted that when trying to get those instances from my TADOQuery connection string builder, the component also failed to get those names.

Is there any way to get them?

image

enter image description here

Issam
  • 133
  • 8
  • Are you compiling your code for 32bit or 64bit? On my 64bit machine, there is no `InstalledInstances` value in the `HKLM\SOFTWARE\Microsoft\Microsoft SQL Serve` key, but there is such a value present in the `HKLM\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server` key instead. – Remy Lebeau Aug 16 '22 at 20:47
  • in my machine the value is exist in the key . Win10 . & it conatins the key value "InstalledInstances" as REG_MULTI_SZ Value . – Issam Aug 16 '22 at 20:57
  • Am compiling for 32bit. – Issam Aug 16 '22 at 21:04
  • 1
    Can you provide a screenshot proving the key exists where you are expecting? Are you looking at the 32bit or 64bit view of the Registry? What is the value of the [`TRegistry.LastError`](https://docwiki.embarcadero.com/Libraries/en/System.Win.Registry.TRegistry.LastError) property when `TRegistry.GetDataSize()` returns `-1`? – Remy Lebeau Aug 16 '22 at 21:49
  • I already attached the screenshot , the value for the TRegistry.LastError is 2. – Issam Aug 16 '22 at 22:14
  • 1
    If the OS is 64 bit you need to check both 32bit and 64 bit registries since SQL Server was available in several releases for each. So do both a `TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY)` and `TRegistry.Create(KEY_READ OR KEY_WOW64_32KEY)` on 64bit Windows. Ref: https://learn.microsoft.com/en-gb/windows/win32/winprog64/accessing-an-alternate-registry-view?redirectedfrom=MSDN and https://stackoverflow.com/questions/12796624/key-wow64-32key-and-key-wow64-64key – Brian Aug 16 '22 at 22:30
  • My Os is 64 bit , & you right @Brian , This solved my question.I used the `TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY)` and it works . Thank you . – Issam Aug 16 '22 at 22:42

0 Answers0