2010-04-19 13 views
6

में काम नहीं कर रही है निम्नलिखित कोड नमूना मुझे विंडोज़ आईडी पहले वापस करने के लिए प्रयुक्त होता है, लेकिन अब यह काम नहीं करता है, और खाली स्ट्रिंग देता है, क्यों नहीं।रजिस्ट्री रीडस्ट्रिंग विधि विंडोज 7 में डेल्फी 7

function GetWindowsID: string; 
    var 
    Registry: TRegistry; 
    str:string; 
    begin 
    Registry := TRegistry.Create(KEY_WRITE); 
    try 
     Registry.Lazywrite := false; 
     Registry.RootKey := HKEY_LOCAL_MACHINE; 
    // Registry.RootKey := HKEY_CURRENT_USER; 
     if CheckForWinNT = true then 
     Begin 
     if not Registry.OpenKeyReadOnly('\Software\Microsoft\Windows NT\CurrentVersion') then showmessagE('cant open'); 
     end 
     else 
     Registry.OpenKeyReadOnly('\Software\Microsoft\Windows\CurrentVersion'); 
     str := Registry.ReadString('ProductId'); 
     result:=str; 
     Registry.CloseKey; 
    finally 
     Registry.Free; 
    end; // try..finally 
    end; 

कोई भी मदद कर सकता है?

उत्तर

23

है ऐसा इसलिए है क्योंकि आभासी कुंजी '\ SOFTWARE \ Wow6432Node \ Microsoft \ Windows NT \ CurrentVersion \' ProductID 'आइटम शामिल नहीं है।

Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); 

जहां KEY_WOW64_64KEY = $ 0100 के साथ TRegistry उदाहरण बनाने के लिए अपने कोड को संशोधित करें। इससे आपको अपेक्षित परिणाम मिलेंगे।

वैकल्पिक रूप से, DSiWin32 का उपयोग करें और फोन

DSiReadRegistry('\Software\Microsoft\Windows NT\CurrentVersion', 
    'ProductID', '', HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE OR KEY_WOW64_64KEY); 
+0

उपयोगी जानकारी है उपयोगी प्रक्रिया कर रहे हैं। मैं DSiWin32 के बारे में नहीं सुना होगा। जेडी पुस्तकालय में समान दिनचर्या से यह बेहतर/अलग कैसे है? –

1

मैं कहना चाहता हूँ कि इस यूएसी के कारण होता है - व्यवस्थापक के रूप में शुरू करने की कोशिश करो!

यदि यह जब व्यवस्थापक के रूप में शुरू किया था, तो आप केवल पढ़ने के लिए मोड का उपयोग करने के अपने पढ़ने के अनुरोध को बदलने की जरूरत (मो पर मेज पर नहीं तो वास्तव में कैसे आप ऐसा याद नहीं कर सकते) काम करता है

संपादित करें:

function GetWindowsID: string; 
var 
    Registry: TRegistry; 
    str:string; 
begin 
    Registry := TRegistry.Create(KEY_READ); 
    try 
    Registry.RootKey := HKEY_LOCAL_MACHINE; 
// Registry.RootKey := HKEY_CURRENT_USER; 
    if CheckForWinNT = true then 
    Begin 
    if not Registry.OpenKeyReadOnly('\Software\Microsoft\Windows NT\CurrentVersion') then showmessage('cant open'); 
    end else 
     Registry.OpenKeyReadOnly('\Software\Microsoft\Windows\CurrentVersion'); 
    str := Registry.ReadString('ProductId'); 
    result:=str; 
    Registry.CloseKey; 
    finally 
    Registry.Free; 
    end; // try..finally 
end; 
0

पढ़ने इसे मैन्युअल RegEdit का उपयोग करें। अनुमति अनुमति के कारण आपको 'एक्सेस अस्वीकृत' मिल सकता है, इस मामले में आप अपने स्तर को देखते हैं और आप इसे कैसे एक्सेस कर रहे हैं।

1

आप इस का उपयोग करते हुए करना चाहिए: TRegistry.Create(KEY_ENUMERATE_SUB_KEYS); खिड़कियां सात यूएसी इस

-2

मेरा मानना ​​है कि क्योंकि

str := Registry.ReadString('ProductId'); 

करता है यह क्रियान्वित करने पर रोक नहीं लगेगी कोई ProductId नहीं होने पर अपवाद नहीं उठाएं। मेरी ईमानदार राय में, यह डेल्फी में एक बग है।

+0

यह winapi है। यह विन्यास वापस करने के लिए है। उपस्थित होने पर डिफ़ॉल्ट होने पर यह मान देता है। – Firo

+0

यह एक बग नहीं है। यह एक विंडोज़ व्यवहार है जैसा ऊपर – Jonesome

3

एक 32 बिट और 64 बिट में पढ़ने के लिए कुंजी रजिस्टर देखने के enviroment.First क्या प्रणाली आप

Type TTypWin32Or64 = (Bit32,Bit64); 
var TypWin32Or64 :TTypWin32Or64; 

Procedure TypeOS(var TypWin32Or64:TTypWin32Or64) ; 
    if DirectoryExists('c:\Windows\SysWOW64') 
    then TypWin32Or64:=Bit64 
    else TypWin32Or64:=Bit32; 

    Procedure for looking Key or Create it in a Registry 
    procedure TForm1.ReadKeyFromRegister(TypWin32Or64:TTypWin32Or64; 
         TypeKey:Longword; {at once symbol HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER} 
         PathToKey:string; 
         TypeValueRead :Integer; //at once symbols as REG_SZ -- string key , 
          //REG_DWORD A DWORD value, a 32-bit unsigned integer 
         NameValueToRead:string; 
         var ValueStrReaded:Ansistring; //is used if it is key string 
         var ValueByteReaded:Pchar; //is used if it is key Byte 
         ReadOnly:boolean); 
var 
    Reg  : TRegistry; 
    S_TStr : TStrings; 
    VersBios : string; 
    Pos0  : integer; 
    Key  : HKEY; 
    Value  : Array of Byte; 
    nValueLen : Integer; 
const KEY_WOW64_64KEY = $0100 ; 
begin 
    case TypWin32Or64 of 
    Bit32: Reg := TRegistry.Create; 
    Bit64:Reg := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); 
    //use if if 64 bit enviroment Windows 
    end; 
try 
    { open key } 
    Reg.RootKey := TypeKey; 
    if ReadOnly 
    then Reg.OpenKeyReadOnly(PathToKey) 
     //not all key can be created or writed ie. ProductId(Serial Key) 
     // name Windows - especially in a 64 bit Windows XP , Win 7 
    else Reg.OpenKey(PathToKey, false); 
     //CreateKey=True--> if this key is not present will be created 
    case TypeValueRead of 
    REG_SZ: ValueStrReaded:=Reg.ReadString(NameValueToRead); 
    REG_BINARY : begin 
        nValueLen := Reg.GetDataSize(NameValueToRead); 
        ValueByteReaded:=Pchar(Reg.ReadBinaryData(NameValueToRead, PByte(Value), nValueLen)); 
       end; 
    REG_DWORD : begin 

       end; 
    REG_MULTI_SZ: begin 
        S_TStr := ReadMultirowKey(Reg,NameValueToRead); 
         /in a enviroment 64 bit not good work - better use  
         //procedure ReadREG_MULTI_SZ 
        VersBios:=S_TStr.Text; 
        Pos0:=Pos(#0,VersBios); 
        if Pos0 > 0 then 
         begin 
         delete(VersBios,Pos0,1); 
         insert(' ', VersBios,Pos0); 
         end; 
        VersBios := StringReplace(VersBios,#$D#$A, ' ' , [rfReplaceAll, rfIgnoreCase]); 
        ValueStrReaded:=VersBios; 
       end; 
     end; //case 
     Reg.CloseKey; 
    finally 
    Reg.Free; 
    end; 
end; 
{------------} 

Sample for reading system Key from Registry 
    Reading UsedWindowsVersion_Full 
    ReadKeyFromRegister(TypWin32Or64, {TypWin32Or64} 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'BuildLabEx', {NameValueToRead:string;} 
          UsedWindowsVersion_Full, {ValueStrReaded:Ansistring;} 
          sPchar ,{ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {-----------------------} 

     For read ProductId(also called Product Key Windows) 
      ReadKeyFromRegister(TypWin32Or64, 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'ProductId', {NameValueToRead:string;} 
          SerialKey, {ValueStrReaded:Ansistring;} 
          sPchar, {ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {------------------------} 
    For reading Product Name 
     ReadKeyFromRegister(TypWin32Or64, 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'ProductName', {NameValueToRead:string;} 
          UsedWindowsName, {ValueStrReaded:Ansistring;} 
          sPchar ,{ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {-----------------------} 
    Procedure for look miltiline key as i.e Version Bios - also 64 envir. 

    procedure TForm1.ReadREG_MULTI_SZ(const CurrentKey: HKey; const 
            Subkey, ValueName: string; 
            Strings: TStrings; var ValueStrRead: String); 
     var 
     valueType: DWORD; 
     valueLen: DWORD; 
     p, buffer: PChar; 
     key: HKEY; 
     begin 
     Strings.Clear; 
      // open the specified key 
     if RegOpenKeyEx(CurrentKey, 
       PChar(Subkey), 
       0, KEY_READ, key) = ERROR_SUCCESS then 
      begin 
      // retrieve the type and data for a specified value name 
      SetLastError(RegQueryValueEx(key, 
      PChar(ValueName), 
      nil, 
      @valueType, 
      nil, 
      @valueLen)); 
      if GetLastError = ERROR_SUCCESS then 
       if valueType = REG_MULTI_SZ then 
        begin 
        GetMem(buffer, valueLen); 
        try 
        // receive the value's data (in an array). 
        RegQueryValueEx(key, 
            PChar(ValueName), 
            nil, 
            nil, 
            PBYTE(buffer), 
            @valueLen); 
        // Add values to stringlist 
        p := buffer; 
        while p^ <> #0 do 
         begin 
         Strings.Add(p); 
         Inc(p, lstrlen(p) + 1) 
         end 
        finally 
         ValueStrRead:=Strings.Text; 
         ValueStrRead:=StringReplace(ValueStrRead,#$D#$A, ' ' , [rfReplaceAll, rfIgnoreCase]); 
         FreeMem(buffer); 
        end 
        end 
       else 
       raise ERegistryException.Create('Stringlist expected') 
        else 
        raise ERegistryException.Create('Cannot Read MULTI_SZ Value/'); 
      end; 
     end; 
     {-----------}  
+0

पर चर्चा की गई है ReadMultirowKey फ़ंक्शन उपरोक्त कोड में अनुपलब्ध है .. [कोड] http://www.sql.ru/forum/955383/readmultirowkey [/ code] पर उपलब्ध है –