7

I'm using a procedure provided to me that'll run a process but I want the process to be run in the background without the window showing up. The call is

 ExecProcess(ProgPath, '', False);

and the function is

function ExecProcess(ProgramName, WorkDir: string; Wait: boolean): integer;
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CreateOK: boolean;
  ExitCode: integer;
  dwExitCode: DWORD;
begin
  ExitCode := -1;

  FillChar(StartInfo, SizeOf(TStartupInfo), #0);
  FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
  StartInfo.cb := SizeOf(TStartupInfo);

  if WorkDir <> '' then
  begin
    CreateOK := CreateProcess(nil, Addr(ProgramName[1]), nil, Addr(WorkDir[1]),
      false, CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS, nil, nil,
      StartInfo, ProcInfo);
  end
  else
  begin
    CreateOK := CreateProcess(nil, Addr(ProgramName[1]), nil, nil, false,
      CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS, nil, Addr(WorkDir[1]),
      StartInfo, ProcInfo);
  end;

  { check to see if successful }

  if CreateOK then
  begin
    // may or may not be needed. Usually wait for child processes
    if Wait then
    begin
      WaitForSingleObject(ProcInfo.hProcess, INFINITE);
      GetExitCodeProcess(ProcInfo.hProcess, dwExitCode);
      ExitCode := dwExitCode;
    end;
  end
  else
  begin
    ShowMessage('Unable to run ' + ProgramName);
  end;

  CloseHandle(ProcInfo.hProcess);
  CloseHandle(ProcInfo.hThread);

  Result := ExitCode;

end;

I have tried to use the StartInfo.wShowWindow attribute with SW_MINIMIZE, SW_FORCEMINIMIZE and SW_SHOWMINIMIZED but it ain't working. I can see that the attribute is changing in the debugger but that's as much as I understand right now. Could someone point out what the problem is?

EDIT: If it matters I'm executing a couple of Fortran modules (.exe) with arguments that'll open up a CMD-window.

Gabriel
  • 20,797
  • 27
  • 159
  • 293
user3464658
  • 229
  • 1
  • 5
  • 14
  • 1
    Is the other process console or GUI app? You have issues with signed and unsigned vars on the exit code. The second param of CreateProcess must be writable. Use UniqueString for that. – David Heffernan Nov 06 '14 at 10:12
  • 1
    Do not use `+` for merging flags `CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS`, you must use `or` operator, like `CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS`. In this case result is same, but in many cases it wont. – Krystian Bigaj Nov 06 '14 at 10:37
  • In addition to what David said about `UniqueString()`, you should also use `PChar(ProgramName)` instead of `Addr(ProgramName[1])`. – Remy Lebeau Nov 06 '14 at 18:13

1 Answers1

11

Use dwFlags with STARTF_USESHOWWINDOW to forced the usage of wShowWindow

StartInfo.wShowWindow := SW_HIDE;
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
bummi
  • 27,123
  • 14
  • 62
  • 101
  • Ups, @TLama sorry having open the the question I just could see `SW_HIDE`, I did not realize the update of the comment. Maybe you should add it as answer and I'll delete mine. – bummi Nov 06 '14 at 09:41
  • 2
    `STARTF_USESHOWWINDOW` only works for GUI apps, and even then it is only a hint, there is no 100% guarantee the app will actually honor it, depending on how it implements its UI. Standard UIs using `ShowWindow()` will honor it, though. For a console app, you can use the `CREATE_NO_WINDOW` flag in the `dwCreationFlags` parameter of `CreateProcess()`. – Remy Lebeau Nov 06 '14 at 18:11