2013-05-07 26 views
-2

如何運行64Bit在64BitOS中編譯PE並停止32Bit在64BitOS中編譯PE?
我有一個Delphi XE2 Project來創建Windows註冊表中的一些節點和子節點如下所述:如何運行64Bit在64BitOS中編譯PE並停止32Bit在64BitOS中編譯PE?

和我的項目編譯選項如下:

我定義了下面的代碼:

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。如何避免這種情況?

我試過Sir Rufo's Solution。我試了下面的代碼:

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解決,但實際問題是編譯器版本正在64Bit環境下運行,並且字符串被編寫爲%SystemRoot%\SysWow64\Application Wizard 01.dll而不是%SystemRoot%\System32\Application Wizard 01.dll

我想我的問題可以解決,如果我只能在Windows 64Bit操作系統中運行64-Bit PE不允許32Bit PE,雖然我的項目同時擁有32位和64位平臺。我不需要編譯兩個不同的PE基於Target Platforms

我也嘗試%SystemRoot%\SysNative\Application Wizard 01.dll後檢測IsWow64Process Function

我也試過BasePointer's solution,它也沒有工作。

所有的排列組合都可以由初學者,我已經嘗試過,但我的問題仍然存在。

+0

您需要在64位系統上運行64位進程,在32位系統上運行32位進程。我已經告訴過你了。您能否從一開始就告訴我們您想要做什麼?你只是試圖註冊一個COM服務器?如果是這樣,應用程序嚮導01.dll是32位還是64位的DLL?如果它是一個32位的DLL,那麼你做的一切都是錯誤的,這個問題不會幫助你。如果「應用程序嚮導01.dll」是一個64位DLL,那麼你可以簡單地讓該DLL執行自注冊。事實上,它幾乎可以肯定已經做到了,所有這些代碼都毫無意義。 – 2013-05-07 18:34:00

+1

你問了很多問題。我們已經回答了他們。我已經回答過這個問題了。你現在需要做的就是不要再問我們如何實現**你所期望的解決方案。你需要做的是告訴我們**問題是什麼。然後讓我們提出解決方案。 – 2013-05-07 18:34:59

+0

號碼。沒有。我試圖純粹開發一個** Windows PE **我的'Application Wizard 01.dll'可能是'32Bit'或'64Bit',這取決於OS架構。所以沒有解決方案。好!謝謝!。再次感謝!請不要生氣。 – user2325284 2013-05-07 18:44:07

回答

1

假設您確實需要寫入註冊表的32位和64位視圖,解決方案如我在earlier question中所述。您需要從32位代碼編寫32位DLL的註冊表項,並從64位代碼編寫64位DLL的註冊表項。

您的問題都來自嘗試修改32位進程的註冊表的64位視圖。註冊表重定向程序阻礙了你這樣做。我在另一個問題中提供的信息足以表明,您無法將您所需的信息從32位進程寫入64位視圖。

+0

沒有DLL註冊。我的要求是隻寫字符串。就這樣。請看我的代碼。我已經在'GetSysNativeDir Function'中使用了註冊表重定向器,並且在檢測到'IsWow64Process Function'後也嘗試了'%SystemRoot%\ SysNative \ Application Wizard 01.dll',但問題是一樣的。 – user2325284 2013-05-07 19:13:01

+0

你在做什麼是DLL註冊!您正在寫入HKCR \ CLSID,COM​​註冊表!好的,我會問你一些嚴重的問題。請儘量回答他們。 1.主機進程是32位,還是需要同時支持32位和64位主機? 2.你編譯了一個64位版本的DLL嗎? 3.什麼讓你覺得你需要使用'KEY_WOW64_64KEY'? 4.你瞭解註冊表重定向程序嗎? – 2013-05-07 19:15:52

+0

我需要支持32位和64位主機,並且這兩個DLL都由Microsoft編譯。當然,第一個是32Bit DLL,最後一個是64Bit DLL,由'PE Explorer'和'CFF Explorer'檢查。我有點理解。 – user2325284 2013-05-07 19:20:31