Introduction
When Microsoft started out to build an x64 version of their OS that could also run 32 bit applications they needed to find a way to unify the Registry so it could serve
either one on a transparent basis. Since this was never foreseen, a typical Microsoft afterthought kludge was cobbled together to make it work. And it does, quite well given
the rather messy nature of the thing. However importing Registry tweaks across 32 and 64 bit versions is problematic.
Background
A friend of mine discovered to his dismay that adding registry tweaks using WPI calling Regedit.exe didn't work as expected when applied in a 64 bit environment,
whilst they worked fine in 32 bit. Not being versed he asked me to look at it. What was happening was that WPI is a 32bit application so the registry entries under
a 64 bit environment didn't get written to the registry rootkey HKEY_LOCAL_MACHINE, whilst all other keys did. Which stood to reason since the WPI called
the 32 bit cmd.exe to execute Regedit.exe only the general keys are written.
Using the code
Since he wanted to continue using the 32 bit WPI I came up with the following solution. The basic principle is to write a Regedit 'Light' compiled to 64 bit that does the registry writing.
The code is in Delphi since i only have a Delphi 64bit CrossCompiler. As i am myself a C programmer who never ever even looked at Delphi i wrote this using a site with Delphi for Beginners
so as Delphi code goes it might not be the very best. But it does the trick. A snippet:
if Pos('[',Temp)>0 then
begin
Rootkeyflag:=true;
Delim:=Pos(']',Temp);
Slash:=Pos('\',Temp);
Rootkey:=MidStr(Temp,2,slash-2);
if Rootkey='HKEY_LOCAL_MACHINE' then OurReg.RootKey:=HKEY_LOCAL_MACHINE;
if Rootkey='HKEY_CURRENT_USER' then OurReg.RootKey:=HKEY_CURRENT_USER;
if Rootkey='HKEY_CLASSES_ROOT' then OurReg.RootKey:=HKEY_CLASSES_ROOT;
if Rootkey='HKEY_CURRENT_CONFIG' then OurReg.RootKey:=HKEY_CURRENT_CONFIG;
if Rootkey='HKEY_USERS' then OurReg.RootKey:=HKEY_USERS;
Subkey:=MidStr(Temp,slash+1,Length(Temp));
Subkey:=LeftStr(Subkey,Length(Subkey)-1);
if Pos('-',Rootkey)>0 then
begin
Rootkey:=RightStr(Rootkey,Length(Rootkey)-1);
Deleteflag:=true;
end
else
begin
Deleteflag:=false;
end;
end;
if (Rootkeyflag) and (not Addvalueflag) then
begin
if Deleteflag then
begin
if Length(Value)>0 then
begin
openResult := OurReg.OpenKey(Subkey,True);
if DeleteKeyflag then
begin
OurReg.GetDataAsString(Temp);
Equalsign:=Pos('=',Temp);
Value:=RightStr(Temp,Length(Temp)-Equalsign);
end;
if openResult then OurReg.DeleteValue(Value);
Key:='';
ActionTaken:=true;
end;
end;
if (not Deleteflag) or (Key='') then
begin
if Length(Key)>0 then
begin
openResult := OurReg.OpenKey(Subkey,True);
if openResult then
begin
ActionTaken:=true;
if Key='@' then Key:='';
case Keytype of
1: try
OurReg.WriteInteger(Key,StrToInt(Value));
except on E: Exception do
OurReg.WriteInteger(Key,0);
end;
2: OurReg.WriteExpandString(Key,Value);
4: OurReg.WriteBinaryData(Key,Value,Length(Value));
5: try
OurReg.WriteFloat(Key,StrToFloat(Value));
except on E: Exception do
OurReg.WriteFloat(Key,0);
end;
6: OurReg.WriteString(Key,Value);
end;
Rootkeyflag:=false;
end;
end;
However using unmodified WPI to make it run, by just adding the resulting 64bit exe to the script doesn't work because the WPI script will
load the 32bit command shell which will choke on the 64bit code. Some out of the box thinking by my friend made him create an selfexecutable
Winrar file with the files in it needed to enter the registry keys and call that in the WPI script which worked like a charm since Winrar executes it correctly.
I assume it'll work with Winzip as well but never tried. This way one can write all keys regardless of which OS version it is using unmodified WPI.
Points of Interest
The nature of Microsoft's kludges are often cause for bewilderment, certainly for those of us who had to suffer through the older api's to get an application to work.
They are poorly documented and usually all over the place. To get this to work really took me to the depths of Microsoft MSDN hell in order to make sense of the whole thing.
Why the registry is kludged as it is is beyond me. Many more elegant solutions are imaginable but i guess it was a case of quick fix that worked most of time so the ostrich
algorithm was applied writing it.