2014-11-06 4 views
5

Ich verwende eine Prozedur, die mir zur Verfügung gestellt wird, die einen Prozess ausführt, aber ich möchte, dass der Prozess im Hintergrund ausgeführt wird, ohne dass das Fenster angezeigt wird. Der Anruf istProzessfenster mit 'CreateProcess' ausblenden

ExecProcess(ProgPath, '', False); 

und die Funktion ist

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 + NORMAL_PRIORITY_CLASS, nil, nil, 
     StartInfo, ProcInfo); 
    end 
    else 
    begin 
    CreateOK := CreateProcess(nil, Addr(ProgramName[1]), nil, nil, false, 
     CREATE_NEW_PROCESS_GROUP + 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; 

Ich habe versucht, das StartInfo.wShowWindow Attribut mit SW_MINIMIZE, SW_FORCEMINIMIZE und SW_SHOWMINIMIZED zu verwenden, aber es funktioniert nicht. Ich kann sehen, dass sich das Attribut im Debugger ändert, aber das ist soweit ich weiß. Könnte jemand darauf hinweisen, was das Problem ist?

EDIT: Wenn es wichtig ist, führe ich ein paar Fortran-Module (.exe) mit Argumenten aus, die ein CMD-Fenster öffnen.

+1

Ist die andere Prozess-Konsole oder GUI-Anwendung zu Zwang? Sie haben Probleme mit signierten und unsignierten vars im Exit-Code. Der zweite Parameter von CreateProcess muss beschreibbar sein. Verwenden Sie dazu UniqueString. –

+1

Verwenden Sie '+' nicht zum Zusammenführen von Flags 'CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS', Sie müssen den Operator' or' verwenden, wie 'CREATE_NEW_PROCESS_GROUP oder NORMAL_PRIORITY_CLASS'. In diesem Fall ist das Ergebnis gleich, aber in vielen Fällen wird es nicht verwendet. – kibab

+0

Zusätzlich zu dem, was David über 'UniqueString()' sagte, sollten Sie auch 'PChar (ProgramName)' anstelle von 'Addr (ProgramName [1])' verwenden. –

Antwort

7

Verwenden dwFlags mit STARTF_USESHOWWINDOW die Verwendung von wShowWindow

StartInfo.wShowWindow := SW_HIDE; 
StartInfo.dwFlags := STARTF_USESHOWWINDOW; 
+0

Vielen Dank, dass Sie sich die Zeit genommen haben, @TLama hat mir die gleiche Lösung gegeben. – user3464658

+0

Ups, @TLama Entschuldigung, die Frage geöffnet zu haben, ich konnte nur 'SW_HIDE' sehen, ich habe das Update des Kommentars nicht bemerkt. Vielleicht solltest du es als Antwort hinzufügen und ich werde meine löschen. – bummi

+1

'STARTF_USESHOWWINDOW' funktioniert nur für GUI-Apps, und auch dann ist es nur ein Hinweis, es gibt keine 100% -Garantie, die die App tatsächlich erfüllen wird, je nachdem, wie sie ihre Benutzeroberfläche implementiert. Standard-UIs, die 'ShowWindow()' verwenden, beachten dies jedoch. Für eine Konsolenanwendung können Sie das Flag 'CREATE_NO_WINDOW' im' dwCreationFlags' -Parameter von 'CreateProcess()' verwenden. –