3

Im on Win 7 64b. Im trying to run msconfig from my delphi app. The msconfig.exe file is in the system32 folder . I copied the msconfig.exe to the c:\ and it works great. This looks like some kind of permission issue.

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;

Has anyone seen this and figured out how to run the msconfig.exe from the sys32 .

RRUZ
  • 134,889
  • 20
  • 356
  • 483
grant1842
  • 357
  • 1
  • 7
  • 23

3 Answers3

6

This behavior is caused by the File System Redirector as workaround you can use the Wow64DisableWow64FsRedirection and Wow64EnableWow64FsRedirection functions.

{$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.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • This is a process-wide setting. If you have running threads in the background that aren't expecting things like this to change, they could be adversely affected. Never mind :-). The documentation says it is thread centric not process centric. – Allen Bauer Oct 11 '12 at 23:53
  • 2
    Instead of disabling FS redirection, you should instead use the special ”SysNative" alias instead of the ”System32" folder directly when running under WOW64 on a 64-bit system: `PChar('C:\Windows\SysNative\msconfig.exe')`. Use `IsWow64Process()` to detect WOW64. – Remy Lebeau Oct 12 '12 at 03:44
  • 1
    Disabling file system redirection is very risky. Please please do not do it. Instead do exactly what Remy said. – David Heffernan Oct 12 '12 at 06:23
3

To access the 64-bit System folder from a 32-bit process, you should use the special ”SysNative" alias instead of the ”System32" folder directly:

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

If you need to support 32-bit OS versions or 64-bit compiling, use IsWow64Process() to detect if your app is running under 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;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    +1 this is how to do it. For what it's worth you may as well test for ver >= 5.2 because 5.1 is 32 bit only. XP64 was 5.2. It was built off server 2003 code base. – David Heffernan Oct 12 '12 at 06:46
  • 1
    +1 too, just `nil` will be better operation for `ShellExecute`. – TLama Oct 12 '12 at 07:22
  • In case anyone tries this out, I found that you need to call `ShellExecute` from an elevated process in order for msconfig to start. But when running a 64 bit process, that was not required. Mysterious. – David Heffernan Oct 12 '12 at 08:45
  • @DavidHeffernan: the calling process does not need to be elevated. msconfig has its own UAC elevation manifest that specifies `requestedExecutionLevel=requireAdministrator`, at least on Win7, so it should get elevated automatically when started. But if your version of msconfig does not have that manifest, you can specify the `"runas"` verb instead of the `"open"` verb when calling `ShellExecute()`, and it will still prompt the user for elevation when starting the msconfig.exe process. – Remy Lebeau Oct 12 '12 at 22:25
  • That's what I thought. I already tried that before I commented. On my system msconfig fails to start from a wow64 process, path specified in sysnative, unless that wow64 process is elevated. Don't understand. – David Heffernan Oct 13 '12 at 07:06
  • thanks for answer. Is there other way to run 64bit explorer.exe from 32 bit app? – mca64 Sep 25 '14 at 19:08
  • 1
    @mca64: Just run `explorer.exe` from the root Windows folder, it will launch the 64bit version. If explorer is already running, it will take over the call and simply open a new window. If you don't want that, you can specify the `/separate` parameter to force a new process, but it will still be 64bit. – Remy Lebeau Sep 25 '14 at 22:05
2

If you're building a 32bit Delphi app, then when it runs on 64bit Windows, the System32 folder is actually remapped. To a 32bit application, System32 is actually SysWOW64. Because you "see" it in System32 from the Explorer or cmd.exe, is because those are 64bit processes. In this case, a 32bit process cannot "see" the actual 64bit System32 folder.

One solution is to get the latest Delphi which supports 64bit targeting and build a 64bit version.

Allen Bauer
  • 16,657
  • 2
  • 56
  • 74