Delphi 7 32 bits execute and wait 64 bits process

delphi, process

Solution

My guess is that the following happens:

- You have a 32 bit process running in the WOW64 emulator under 64 bit Windows.

- You attempt to start a new process named `mstsc.exe`.

- The system searches on the path for that and finds it in the system directory.

- Because you run under WOW64, the system directory is the 32 bit system directory, SysWOW64.

- The process starts and immediately detects that it is a 32 bit process running under WOW64 under a 64 bit system.

- The 32 bit `mstsc.exe` then determines that it needs to start the 64 bit version of `mstsc.exe`, which it does, passing on any command line arguments, and then immediately terminates.

This would explain why your new process immediately terminates.

Some possible solutions:

- Disable file system redirection before you start the new process. Obviously you should re-enable it immediately afterwards.

- Create a small 64 bit program that lives in the same directory as your executable, whose sole job is to launch programs. You can start this process and ask it to launch the other process. That would allow you to escape from the clutches of the emulator and its redirection.

Problem

I used to use the function below to start and wait unil the end of a process. It works fine for starting and waiting for 32 bits process on a 32 bits or 64 bits OS. But on a 64 bits OS, it returns immediately when i launch a 64 bits process (WaitForSingleObject = WAIT_OBJECT_0). For example, if my app (32 bits), launch mstsc.exe on a 32 bits OS it is ok but it don't wait on a 64 bits OS certainly because mstsc.exe is a 64 bits program. Any solution ? ``` function gShellExecuteAndWait( vHandle : HWND; vOperation : string; vFichier : string; vParametres : string; vRepertoire : string; vAffichage : Integer; vDuree : DWORD; var vErreur : string ) : Boolean; var vSEInfo : TShellExecuteInfo; vAttente : DWORD; begin // Initialisation Result := True; vErreur := ''; vAttente := 0; // Initialisation de la structure ShellExecuteInfo ZeroMemory(@vSEInfo, SizeOf(vSEInfo)); // Remplissage de la structure ShellExecuteInfo vSEInfo.cbSize := SizeOf(vSEInfo); vSEInfo.fMask := SEE_MASK_NOCLOSEPROCESS; vSEInfo.Wnd := vHandle; vSEInfo.lpVerb := PAnsiChar(vOperation); vSEInfo.lpFile := PAnsiChar(vFichier); vSEInfo.lpParameters := PAnsiChar(vParametres); vSEInfo.lpDirectory := PAnsiChar(vRepertoire); vSEInfo.nShow := vAffichage; // L'exécution a réussi if ShellExecuteEx(@vSEInfo) then begin // Attendre la fin du process ou une erreur while True do begin case WaitForSingleObject(vSEInfo.hProcess, 250) of WAIT_ABANDONED : begin Result := False; vErreur := 'L''attente a été annulée.'; Break; end; WAIT_OBJECT_0 : begin Break; end; WAIT_TIMEOUT : begin // Initialisation vAttente := vAttente + 250; // Le délai d'attente n'a pas été atteint if vAttente < vDuree then begin Application.ProcessMessages(); end // Le délai d'attente est dépassé else begin Result := False; vErreur := 'Le délai d''attente a été dépassé.'; Break; end; end; WAIT_FAILED : begin Result := False; vErreur := SysErrorMessage(GetLastError()); Break; end; end; end; end // L'exécution a échoué else begin Result := False; vErreur := SysErrorMessage(GetLastError()); end; end; ```

Original source