The following code sample used to return me windows id before, but now it doesn't work, and returns empty string, dunno why.
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;
Anybody can help?
That is because the virtualized key '\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\' doesn't contain the 'ProductID' item.
Modify your code to create the TRegistry instance with
Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);
where KEY_WOW64_64KEY = $0100. That will give you the expected result.
Alternatively, use DSiWin32 and call
DSiReadRegistry('\Software\Microsoft\Windows NT\CurrentVersion',
'ProductID', '', HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE OR KEY_WOW64_64KEY);
There are usefull procedure to read Key Register in a 32 bit and 64 bit enviroment.First look what system you have
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;
{-----------}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With