如何在 64BitOS 中运行 64Bit Compiled PE 并在 64BitOS 中停止 32Bit Compiled PE?
我有一个Delphi XE2 项目来在 Windows 注册表中创建一些节点和子节点,如下所述:
和我的项目编译器选项如下:
我已经定义了以下代码:
function GetWinDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory);
end;
function GetSysDir: string;
var
SystemDirectory: array[0..MAX_PATH] of Char;
begin
GetSystemDirectory(SystemDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(SystemDirectory));
Result := IncludeTrailingPathDelimiter(SystemDirectory);
end;
function GetSysNativeDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory) + 'Sysnative\';
end;
procedure TMainForm.BitBtn01Click(Sender: TObject);
var
RegistryEntry : TRegistry;
RegistryEntryValue : string;
begin
RegistryEntry := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
RegistryEntry.RootKey := HKEY_CLASSES_ROOT;
if (not RegistryEntry.KeyExists('CLSID\{BE800AEB-A440-4B63-94CD-AA6B43647DF9}\')) then
begin
RegistryEntry.Access:= KEY_WRITE or KEY_WOW64_64KEY;
if RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\',true) then
begin
Memo01.Font.Color := 3992580;
Memo01.Lines.Add('Windows Registry Entry Has Been Found In Your System');
RegistryEntry.WriteString('', 'Delphi Application Wizard');
RegistryEntry.OpenKey('Subnode 01\',true);
RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 01.dll');
RegistryEntry.WriteString('Subnode String 01', '00001');
RegistryEntry.CloseKey();
RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 02\',true);
RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 02.dll');
RegistryEntry.WriteString('Subnode String 02', '00002');
RegistryEntry.CloseKey();
RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 03\',true);
RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 03.dll');
RegistryEntry.WriteString('Subnode String 03', '00003');
RegistryEntry.CloseKey();
RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 04\',true);
RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 04.dll');
RegistryEntry.WriteString('Subnode String 04', '00004');
RegistryEntry.CloseKey();
RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 05\',true);
RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 05.dll');
RegistryEntry.WriteString('Subnode String 05', '00005');
Memo01.Font.Color := 3992580;
Memo01.Lines.Add('Windows Registry Entry Has Been Created Successfully')
end
else if RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\',false) then
begin
Memo01.Font.Color := 7864575;
Memo01.Lines.Add('Windows Registry Entry Has Not Been Created Successfully')
end
end
else
begin
if (RegistryEntry.KeyExists('CLSID\{00000000-0000-0000-0000-000000000001}\')) then
begin
Memo01.Font.Color := 7864575;
Memo01.Lines.Add('Windows Registry Entry Has Been Found In Your System')
end;
end;
RegistryEntry.CloseKey();
RegistryEntry.Free;
end;
我的问题是:
尽管我正在尝试为%SystemRoot%\System32\Application Wizard 01.dll
尚未%SystemRoot%\SysWow64\Application Wizard 01.dll
写入的每个子节点编写默认字符串。如何避免这种情况?
我已经尝试过Rufo 爵士的解决方案。我尝试了以下代码:
const
RegistryEntry = 'CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01';
RegistryEntryString = '%SystemRoot%\System32\Application Wizard 01.dll';
type
TGetInfoFunc = function : WideString; stdcall;
function ExpandEnvironmentStringsStr( const AStr : string ) : string;
begin
SetLength( Result, ExpandEnvironmentStrings( PChar( AStr ), nil, 0 ) );
ExpandEnvironmentStrings( PChar( AStr ), PChar( Result ), Length( Result ) );
end;
function GetWinDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory);
end;
function GetSysDir: string;
var
SystemDirectory: array[0..MAX_PATH] of Char;
begin
GetSystemDirectory(SystemDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(SystemDirectory));
Result := IncludeTrailingPathDelimiter(SystemDirectory);
end;
function GetSysNativeDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory) + 'Sysnative\';
end;
procedure TMainForm.BitBtn01Click(Sender: TObject);
var
LReg : TRegistry;
LRegDataInfo : TRegDataInfo;
LDllFileName : string;
LLib : HMODULE;
LFunc : TGetInfoFunc;
LStr : string;
begin
LReg := TRegistry.Create;
try
LReg.RootKey := HKEY_CLASSES_ROOT;
if LReg.OpenKeyReadOnly( RegistryEntry )
then
if LReg.GetDataInfo( '', LRegDataInfo )
then
begin
case LRegDataInfo.RegData of
rdString : //Just Read The Existing String
LDllFileName := LReg.ReadString( '' );
rdExpandString : //String Needs To Be Expanded
LDllFileName := ExpandEnvironmentStringsStr( LReg.ReadString( '' ) );
end;
end;
finally
LReg.Free;
end;
Label01.Caption := LDllFileName; //Just For Information
//No Information From Registry
if LDllFileName = ''
then
raise Exception.Create( 'Not registered' );
//Load The Library
LLib := LoadLibrary( PChar( LDllFileName ) );
if LLib <> 0
then
try
@LFunc := GetProcAddress( LLib, 'GetInfo' );
LStr := LFunc;
finally
FreeLibrary( LLib );
end
else
raise Exception.CreateFmt( 'Dll-File "%s" not found!', [LDllFileName] );
//Show The Information
ShowMessage( LStr );
end;
procedure TMainForm.BitBtn02Click(Sender: TObject);
var
LReg : TRegistry;
begin
LReg := TRegistry.Create;
try
LReg.RootKey := HKEY_CLASSES_ROOT;
if LReg.OpenKey( RegistryEntry, True )
then
try
//We Write As REG_EXPAND_SZ To Flag That This Contain Environment Variables That Has To Be Expanded
LReg.WriteExpandString( '', RegistryEntryString );
finally
LReg.CloseKey;
end
else
raise Exception.CreateFmt( 'Not allowed to create the registry key HKCR\%s', [RegistryEntryString] );
finally
LReg.Free;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Caption := Application.Title{$IFDEF WIN64} + ' Win64'{$ELSE} + ' Win32'{$ENDIF};
end;
但它不起作用。注册表项写在下面[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01]
虽然不是实际问题,但可以用 解决RegistryEntry.Access:= KEY_WRITE or KEY_WOW64_64KEY
,但实际问题是32Bit
编译器版本是在64Bit
环境下运行的,字符串写成%SystemRoot%\SysWow64\Application Wizard 01.dll
而不是%SystemRoot%\System32\Application Wizard 01.dll
.
64-Bit PE
我认为,如果我只能在不允许的 Windows 64Bit 操作系统中运行,我的问题可以解决32Bit PE
,尽管我的项目同时具有 32 位和 64 位平台。我不需要基于编译两个不同的 PETarget Platforms
%SystemRoot%\SysNative\Application Wizard 01.dll
检测后我也试过了IsWow64Process Function
。
我也尝试过BasePointer 的解决方案,它也不起作用。
初学者可以进行所有排列和组合,我已经尝试过,但我的问题仍然存在。