regsiter anahtara ulaşamıyorum

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
tayipk
Üye
Mesajlar: 284
Kayıt: 27 Kas 2013 11:32

regsiter anahtara ulaşamıyorum

Mesaj gönderen tayipk »

arkadaşlar merhaba söyle bir sorunum var. registerdan bilgi çekmek istiyorum

Kod: Tümünü seç

begin
  registr:=TRegistry.Create;
  with registr do
  begin
    RootKey:=HKEY_LOCAL_MACHINE;
    OpenKey('Software\Microsoft',False);
    if KeyExists('Microsoft SQL Server') then
    begin
      ShowMessage('OK');
    end;

    timer3.Enabled:=False;
  end;
  end;
bunda sıkıntı yok ama

Kod: Tümünü seç

OpenKey('Software\Microsoft',False);
bölümünü

Kod: Tümünü seç

OpenKey('Software\Microsoft\Microsoft SQL Server\Instance Names\SQL',False);
şeklinde değiştirince kod işlemiyor benim derdim Software\Microsoft\Microsoft SQL Server\Instance Names\SQL deki isntance nameleri çekmek ama başaramadım. bu konuda yardımlarınıza ihtiyacım var.yardımlarınız için şimdiden teşekkürederim.
Soru Sorarken yazmaya Üşenmeyen Parmaklar Sorunun Çözüldükten Sonra Teşekkür etmeye de Üşenmesin.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: regsiter anahtara ulaşamıyorum

Mesaj gönderen mrmarman »

Merhaba..

- Aşağıdaki yapıyı deneyebilirsin. 64 bit işletim sistemi için de aynı fonksiyona dahil edildi.

Fonksiyon :

Kod: Tümünü seç

USES Registry;

function SQLInstanceList(Liste: TStrings): Boolean;
  function Is64BitOS: Bool;
  type
    TIsWow64Process = function(Handle:THandle; var IsWow64 : Boolean) : Boolean; stdcall;
  var
    hKernel32 : Integer;
    IsWow64Process : TIsWow64Process;
    IsWow64 : Boolean;
  begin
    Result := False;
    hKernel32 := LoadLibrary('kernel32.dll');
    try
      if (hKernel32 = 0) then RaiseLastOSError;
      @IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process');
      if Assigned(IsWow64Process) then
      begin
        IsWow64 := False;
        if (IsWow64Process(GetCurrentProcess, IsWow64))
          then Result := IsWow64
          else RaiseLastOSError;
      end;
    finally
      FreeLibrary(hKernel32);
    end;
  end;

  function RegAccess: Cardinal;
  begin
    Result:= KEY_READ or KEY_WRITE;
    if Is64BitOS then
      Result:= Result or KEY_WOW64_64KEY;
  end;
const
  SQL_INSTANCES_KEY = 'Software\Microsoft\Microsoft SQL Server\Instance Names\SQL\';
var
  R: TRegistry;
begin
  Result:= False;
  Liste.Clear;
  R:= TRegistry.Create(RegAccess);
  try
    R.RootKey:= HKEY_LOCAL_MACHINE;
    if R.KeyExists(SQL_INSTANCES_KEY) then begin
      if R.OpenKey(SQL_INSTANCES_KEY, False) then begin
        try
          R.GetValueNames(Liste);
          Result:= True;
        finally
        end;
        R.CloseKey
      end;
    end;
  finally
    R.Free;
  end;
end;
Kullanımı :

Kod: Tümünü seç

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  SQLInstanceList( Memo1.Lines );
end;
Resim
Resim ....Resim
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: regsiter anahtara ulaşamıyorum

Mesaj gönderen sabanakman »

İyi günler. Muharrem Hocam bir kaç dakika erken davranmış :mrgreen: . Açıkçası bir zamanlar SQL Server listesini Registry üzerinden okumaya çalıştım ama sistemde hem x86, hem de x64 bit sql yüklü ise iki defa registry okuma yapmak gerekmektedir. Bu durum yukarıdaki R.GetValueNames kodlaması için de geçerli maalesef. Zira bu platform farkından doğan registry kayıtları birbirinden bağımsız olarak erişilmektedir ve her SQL Server kendi platformuna göre registry değeri oluşturmaktadır. Ayrıca HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server anahtarında bulunan InstalledInstances değeri string değil, multistring tipinde olduğu için bu bilgiyi string olarak ele almadan yorumlamak gerekmektedir. Bir zamanlar aşağıdaki yöntemle SQL Listesini alıyordum :mrgreen:

Kod: Tümünü seç

uses Registry;

procedure GetInstanceNames(const Names:TStrings;Server:String='';BosSatirEkle:Boolean=True;const x64mu:Boolean=False);
const KEY_WOW64_64KEY=$0100;
var
  Info: TRegDataInfo;
  Bilgi:PByteArray;
  S:PChar;
  i:Integer;
  Duzgun:Boolean;
  RegParam:Cardinal;
begin //S:='?';
  Server:=Trim(Server);
  if SameText(Server,'(local)') or SameText(Server,'.') then Server:='';
  if x64mu then RegParam:=KEY_READ OR KEY_WOW64_64KEY else RegParam:=KEY_READ;
  with TRegistry.Create(RegParam) do try
    RootKey:=HKEY_LOCAL_MACHINE;
    if Trim(Server)<>'' then
     if not RegistryConnect(Server) then Application.MessageBox(PChar(Format('%s sunucusu okunamıyor',[Server])),'Hata',MB_ICONERROR);
    //RegistryConnect(Sunucu);
    OpenKey('SOFTWARE\Microsoft\Microsoft SQL Server',False);
    Bilgi:=nil;
    if GetDataInfo('InstalledInstances', Info) then try
      Bilgi:=AllocMem(Info.DataSize);
      ReadBinaryData('InstalledInstances',Bilgi^,Info.DataSize);
      Names.BeginUpdate;
      Names.Clear;
      //if Length(S)<-1 then ShowMessage(S);
      S:=@(Bilgi^);
      //if Length(S)<-1 then ShowMessage(S);
      repeat
        //if Trim(S)='' then Break ya da
        if SameText('MSSQLSERVER',S) then Names.Add('') else begin
          i:=Length(S)-1; Duzgun:=True;
          while Duzgun and (i>0) do begin
            Duzgun:=(S[i]>#31);
            Dec(i);
          end;
          if Duzgun then Names.Add(S);
        end;
        S:=Pointer(Integer(S)+Length(S)+1)
      until (S='') or (S[1]=#0);
    finally
      Names.EndUpdate;
      if Assigned(Bilgi) then FreeMem(Bilgi);
    end;
  finally
    Free;
  end;
end;
Bu fonksiyonu aşağıdaki gibi 32 bit ve 64 bit sql isimlerini alabilmek için 2 kere çağırmak gerekiyor.

Kod: Tümünü seç

GetInstanceNames(ListBox1.Items,'',True,False);//<-x86 sql ler
GetInstanceNames(ListBox2.Items,'',True,True);//<-x64 sql ler
Ama bir zaman sonra SQL Server listesini hizmetler listesinden elde edilebileceği fikrine kapıldım ve gördüğüm kadarı ile bu hizmet eğer instancename'e sahip değilse MSSQLSERVER adını alıyor ama bir instancename varsa MSSQL$INSTANCENAME gibi bir hizmet oluşturmakta. Bu mantıkla aşağıdaki gibi başka bir fonksiyon kullandım ve şu an onu kullanmaktayım.

Kod: Tümünü seç

uses StrUtils, WinSvc;

function GetSQLServiceList(sMachine:string;dwServiceType,dwServiceState:DWord;slServicesList:TStrings):Boolean;
const
  cnMaxServices = 4096;

  SERVICE_KERNEL_DRIVER       = $00000001;
  SERVICE_FILE_SYSTEM_DRIVER  = $00000002;
  SERVICE_ADAPTER             = $00000004;
  SERVICE_RECOGNIZER_DRIVER   = $00000008;
  SERVICE_DRIVER              =
    (SERVICE_KERNEL_DRIVER or
     SERVICE_FILE_SYSTEM_DRIVER or
     SERVICE_RECOGNIZER_DRIVER);

  SERVICE_WIN32_OWN_PROCESS   = $00000010;
  SERVICE_WIN32_SHARE_PROCESS = $00000020;
  SERVICE_WIN32               =
    (SERVICE_WIN32_OWN_PROCESS or
     SERVICE_WIN32_SHARE_PROCESS);

  SERVICE_INTERACTIVE_PROCESS = $00000100;

  SERVICE_TYPE_ALL            =
    (SERVICE_WIN32 or
     SERVICE_ADAPTER or
     SERVICE_DRIVER  or
     SERVICE_INTERACTIVE_PROCESS);
type
  TSvcA = array[0..cnMaxServices] of TEnumServiceStatus;
  PSvcA = ^TSvcA;
var
  j:integer;
  schm:SC_Handle;
  nBytesNeeded,nServices,nResumeHandle : DWord;
  ssa : PSvcA;
  DefaultSQL:Boolean;//MSSQLSERVER varsa true
 procedure isSQLService(ServiceName:String);
 const
   MSSQLSERVER='MSSQLSERVER'; //LenMSSQLSERVER=11;
   MSSQL='MSSQL$'; LenMSSQL=6;
   //MSSQL$SQL2008,MSSQL$SQL2012
 begin
   if SameText(ServiceName,MSSQLSERVER) then DefaultSQL:=True
   else if SameText(MSSQL,LeftStr(ServiceName,LenMSSQL)) then begin
     Delete(ServiceName,1,LenMSSQL);
     slServicesList.Add(ServiceName);
   end;
 end;
begin
  Result := False;
  DefaultSQL:=False;
  slServicesList.Clear;
  schm := OpenSCManager(PChar(sMachine),nil,SC_MANAGER_ALL_ACCESS);
  if(schm > 0)then begin
    nResumeHandle := 0;
    New(ssa);
    EnumServicesStatus(schm,dwServiceType,dwServiceState,ssa^[0],SizeOf(ssa^),
     nBytesNeeded,nServices,nResumeHandle );
    for j := 0 to nServices-1 do begin
      //slServicesList.Add(StrPas(ssa^[j].lpServiceName{lpDisplayName{} ) );
      isSQLService(ssa^[j].lpServiceName);
    end;
    if DefaultSQL then slServicesList.Insert(0,'');//default olan sql en üste...
    Result := True;
    Dispose(ssa);
    // close service control 
    // manager handle 
    CloseServiceHandle(schm); 
  end; 
end;
Bu foksyionu da aşağıdaki gibi kullandığımda sistemde yüklü olan bütün sql server instancename listesini elde edebildim.

Kod: Tümünü seç

GetSQLServiceList('',SERVICE_WIN32,SERVICE_STATE_ALL,ListBox1.Items);
İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
tayipk
Üye
Mesajlar: 284
Kayıt: 27 Kas 2013 11:32

Re: regsiter anahtara ulaşamıyorum

Mesaj gönderen tayipk »

sayın uharrem hocam yolladığınız function ile sorunum çözülmüştür elinize sağlık. şaban hocam sizede cevabınız için teşekkürederim
Soru Sorarken yazmaya Üşenmeyen Parmaklar Sorunun Çözüldükten Sonra Teşekkür etmeye de Üşenmesin.
Cevapla