2012-10-11 43 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位进程时,这不是必需的。神秘。 –