2014-11-06 54 views
5

我正在使用提供给我的程序来运行一个进程,但我希望进程在后台运行而不显示窗口。电话是使用'CreateProcess'隐藏进程窗口

ExecProcess(ProgPath, '', False); 

而且功能

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; 

我曾尝试使用StartInfo.wShowWindow属性与SW_MINIMIZESW_FORCEMINIMIZESW_SHOWMINIMIZED,但它不工作。我可以看到该属性在调试器中发生了变化,但这与我目前所了解的一样。有人能指出问题是什么吗?

编辑:如果它很重要我正在执行一些Fortran模块(.exe)与参数,将打开一个CMD窗口。

+1

的使用是其他程序控制台或GUI应用程序?退出代码中的签名和未签名变量有问题。 CreateProcess的第二个参数必须是可写的。为此使用UniqueString。 – 2014-11-06 10:12:42

+1

不要使用'+'来合并标志'CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS',你必须使用'或'运算符,比如'CREATE_NEW_PROCESS_GROUP或NORMAL_PRIORITY_CLASS'。在这种情况下,结果是一样的,但在很多情况下,结果是一样的。 – kibab 2014-11-06 10:37:35

+0

除了David关于'UniqueString()'的说法外,还应该使用'PChar(ProgramName)'而不是'Addr(ProgramName [1])'。 – 2014-11-06 18:13:39

回答

7

使用dwFlags中与STARTF_USESHOWWINDOW强迫的wShowWindow

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

感谢您抽出宝贵的时间,@TLama给了我相同的解决方案。 – user3464658 2014-11-06 09:38:54

+0

Ups,@TLama抱歉打开了我只能看见'SW_HIDE'的问题,我没有意识到这个评论的更新。也许你应该添加它作为答案,我会删除我的。 – bummi 2014-11-06 09:41:09

+1

'STARTF_USESHOWWINDOW'只适用于GUI应用程序,即使这只是一个提示,也不能100%保证应用程序会实际遵守它,这取决于它如何实现其UI。不过,使用'ShowWindow()'的标准用户界面将会尊重它。对于控制台应用程序,可以使用'CreateProcess()'的'dwCreationFlags'参数中的'CREATE_NO_WINDOW'标志。 – 2014-11-06 18:11:06