2012-10-11 75 views
3

我在Win 7 64b上運行。 我試圖從我的delphi應用程序運行msconfig。 msconfig.exe文件位於system32文件夾中。 我將msconfig.exe複製到c:\中,效果很好。 這看起來像某種權限問題。無法獲取msconfig.exe在system32文件夾中運行德爾福

var 
errorcode: integer; 
begin 
    errorcode := 
ShellExecute(0, 'open', pchar('C:\Windows\System\msconfig.exe'), nil, nil, SW_NORMAL); 
if errorcode <= 32 then 
ShowMessage(SysErrorMessage(errorcode)); 
end; 

有沒有人看到這個,並想出瞭如何從sys32運行msconfig.exe。

+0

什麼是你看到錯誤消息? – RobertFrank

+0

*系統找不到指定的文件*? – TLama

回答

6

此行爲是由File System Redirector作爲解決方法,您可以使用Wow64DisableWow64FsRedirectionWow64EnableWow64FsRedirection功能。

{$APPTYPE CONSOLE} 


uses 
    ShellAPi, 
    SysUtils; 

Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall; 
    External 'Kernel32.dll' Name 'Wow64DisableWow64FsRedirection'; 
Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall; 
    External 'Kernel32.dll' Name 'Wow64EnableWow64FsRedirection'; 


Var 
    Wow64FsEnableRedirection: LongBool; 

begin 
    try 
    Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection); 
    ShellExecute(0, nil, PChar('C:\Windows\System32\msconfig.exe'), nil, nil, 0); 
    Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

哇這些功能像一個魅力工作謝謝你的幫助。 – grant1842

+0

這是一個過程範圍的設置。如果你在後臺運行的線程不希望這樣的事情發生改變,它們可能會受到不利影響。 沒關係:-)。文檔說它是以線程爲中心而不是以過程爲中心的。 –

+2

而不是禁用FS重定向,而應該在64位系統上的WOW64下運行時直接使用特殊的「SysNative」別名而不是「System32」文件夾:'PChar('C:\ Windows \ SysNative \ msconfig.exe 「)'。使用'IsWow64Process()'來檢測WOW64。 –

2

如果您正在構建一個32位Delphi應用程序,那麼當它運行在64位Windows上時,System32文件夾實際上會被重新映射。對於32位應用程序,System32實際上是SysWOW64。因爲你從Explorer或cmd.exe在System32中「看到」它是因爲那些是64位進程。 在這種情況下,32位進程無法「看見」實際的64位System32文件夾。

一個解決方案是獲得支持64位定位和構建64位版本的最新Delphi。

3

從一個32位的過程中,你應該使用特殊的「SysNative」的別名,而不是「System32" 下文件夾直​​接訪問64位的系統文件夾:

PChar('C:\Windows\SysNative\msconfig.exe') 

如果您需要支持32位操作系統版本或64位編譯,使用IsWow64Process()來檢測,如果您的應用程序下運行的WOW64:

{$IFDEF WIN64} 
function IsWow64: Boolean; 
begin 
    Result := False; 
end; 
{$ELSE} 
function IsWow64Process(hProcess: THandle; out Wow64Process: BOOL): BOOL; stdcall; external 'kernel32.dll' delayed; 

function IsWow64: Boolean; 
var 
    Ret: BOOL; 
begin 
    Result := False; 
    // XP = v5.1 
    if (Win32MajorVersion > 5) or 
    ((Win32MajorVersion = 5) and (Win32MinorVersion >= 1)) then 
    begin 
    if IsWow64Process(GetCurrentProcess(), Ret) then 
     Result := Ret <> 0; 
    end; 
end; 
{$ENDIF} 

var 
    errorcode: integer; 
    SysFolder: string; 
begin 
    If IsWow64 then 
    SysFolder := 'SysNative' 
    else 
    SysFolder := 'System32'; 
  errorcode := ShellExecute(0, 'open', PChar('C:\Windows\'+SysFolder'+\msconfig.exe'), nil, nil, SW_NORMAL); 
    if errorcode <= 32 then 
    ShowMessage(SysErrorMessage(errorcode)); 
end; 
+1

+1這是怎麼做到的。對於它的價值,你也可以測試ver> = 5.2,因爲5.1只是32位。 XP64是5.2。它基於server 2003代碼庫構建而成。 –

+1

+1,只是'nil'對於'ShellExecute'會更好。 – TLama

+0

如果有人嘗試這樣做,我發現你需要從一個提升的進程調用'ShellExecute'爲了啓動msconfig。但是,當運行64位進程時,這不是必需的。神祕。 –