来回答老菜这个简单问题,50分相送(50分)

W

wgjxnm

Unregistered / Unconfirmed
GUEST, unregistred user!
在调用多个外部程序<br>begin<br>winexec(程序1);<br>winexec(程序2);<br>winexec(程序3);<br>winexec(程序4);<br>winexec(程序5);<br>end;<br><br>怎么让程序单独运行完一个程序后再运行一个程序,上<br>面的代码似乎在同时运行这5个程序,请大家来帮帮我~~<br><br>
 
{****************************************}<br>&nbsp; &nbsp; &nbsp; &nbsp;{执行其他可执行程序,等待它执行完毕再继续执行自己,否则阻塞}<br>{****************************************}<br>function TFrm1.ExecAndWait(const Filename, Params: string; WindowState: word): boolean;<br>var &nbsp;SUInfo: TStartupInfo;<br>&nbsp; &nbsp; &nbsp;ProcInfo: TProcessInformation;<br>&nbsp; &nbsp; &nbsp;CmdLine: string;<br>begin<br>&nbsp; CmdLine := '"' + Filename + '"' + Params; { 注意检查长文件名}<br>&nbsp; FillChar(SUInfo, SizeOf(SUInfo), #0);<br>&nbsp; with SUInfo do begin<br>&nbsp; &nbsp; cb := SizeOf(SUInfo);<br>&nbsp; &nbsp; dwFlags := STARTF_USESHOWWINDOW;<br>&nbsp; &nbsp; wShowWindow := WindowState;<br>&nbsp; end;<br><br>&nbsp; Result := CreateProcess(NIL, PChar(CmdLine), NIL, NIL,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FALSE,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, NIL,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PChar(ExtractFilePath(Filename)), SUInfo, ProcInfo);<br>&nbsp; if Result then &nbsp;{等待结束 }<br>&nbsp; begin<br>&nbsp; &nbsp; &nbsp;WaitForSingleObject(ProcInfo.hProcess, INFINITE);<br>&nbsp; &nbsp; &nbsp;CloseHandle(ProcInfo.hProcess); &nbsp; &nbsp; {清理句柄 }<br>&nbsp; &nbsp; &nbsp;CloseHandle(ProcInfo.hThread);<br>&nbsp; end;<br>end;
 
能不能详细解释一下这个函数的各类参数~~~~~~~~~~~~~~~~我有点看不太懂~~~<br>
 
只是用两个CreateProcess,和WaitForSingleObject。<br>给你找了一片文章,挺长的,希望仔细看完,看完后基本就懂了。<br>http://lijun_1.myetang.com/asm/win32/lyb-tut11-process.htm<br><br>进程控制简单的说相当于在一个程序中执行另一个程序,你可以把它想象成在 Dos 下用 int 21h/4bh 功能来执行另外一个程序,如果单从执行另一个程序的目的来讲,在 Windows 中有不少方法,如使用 ShellExecute 等,但这些 Api 仅仅是“执行”而已,进程控制的意义在于可以创建一个进程,并可以通过进程句柄结束进程,同样你也可以通过进程句柄来跟踪程序,还可以用 ReadProcessMemory 和 WriteProcessMemory 来读写子进程的内存空间。<br><br>进程控制要使用的相关 API 有下面这些:<br><br>创建进程的函数为CreateProcess,该函数比较复杂,共有十个参数,但有个好消息是使用时大部分可以用 NULL。<br><br>BOOL CreateProcess( <br>LPCTSTR lpApplicationName, // 执行程序文件名<br>LPTSTR lpCommandLine, // 参数行 <br>LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全参数<br>LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全参数<br>BOOL bInheritHandles, // 继承标记<br>DWORD dwCreationFlags, // 创建标记<br>LPVOID lpEnvironment, // 环境变量<br>LPCTSTR lpCurrentDirectory, // 运行该子进程的初始目录<br>LPSTARTUPINFO lpStartupInfo, // 创建该子进程的相关参数 <br>LPPROCESS_INFORMATION lpProcessInformation // 创建后用于被创建子进程的信息<br>);<br><br>各个参数的说明如下:<br><br>lpApplicationName:为执行程序的文件名,你也可以把执行文件名包括在下一个参数 lpCommandLine 中,然后把该参数置为NULL。 <br>lpCommandLine:为参数行,如果无参数可以为NULL,在有参数传递给进程时可以如下设置:lpApplicationName=文件名;lpCommandLine=参数,或者 lpApplicationName=NULL;lpCommandLine=文件名 + 参数。 <br>lpProcessAttributes,lpThreadAttributes:分别描述了创建的进程和线程安全属性,如果使用NULL表示使用默认的安全描述。 <br>bInheritHandles:表示当前进程中的打开的句柄是否能够被创建的子进程所继承。 <br>dwCreationFlags:表示创建标记,通过该标记可以设置进程的创建状态和优先级别。常用的有下面的标记: <br>CREATE_NEW_CONSOLE:为子进程创建一个新的控制台。 <br>CREATE_SUSPENDED:子进程在创建时为挂起状态。如果指定了这个参数,那么执行 CreateProcess 后进程只是被装入内存,但不是马上开始执行,而是必须等主程序调用 ResumeThread 后才继续执行。<br>HIGH_PRIORITY_CLASS/NORMAL_PRIORITY_CLASS:高/普通优先级别。 <br>lpEnvironment:表示子进程所使用的环境变量,如果为NULL,则表示与当前进程使用相同的环境变量。 <br>lpCurrentDirectory:表示子进程运行的初始目录。 <br>lpStartupInfo:STARTUPINFO 结构,用于在创建子进程时设置各种属性。 <br>lpProcessInformation:PROCESS_INFORMATION 结构,用来在进程创建后接收相关信息,该结构由系统填写。 <br>调用 CreateProcess 函数有三个参数是必需的,一在 lpApplicationName 或 lpCommandLine 指定文件名,二是 lpStartupInfo 结构,三是 PROCESS_INFORMATION 结构,因为 PROCESS_INFORMATION 结构返回了进程建立后的句柄,以后的一切操作将要用到这些返回的句柄,它是由系统填写的,结构说明如下:<br><br>typedef struct _PROCESS_INFORMATION { <br>HANDLE hProcess; //进程句柄<br>HANDLE hThread; //进程的主线程句柄<br>DWORD dwProcessId; //进程ID<br>DWORD dwThreadId; //进程的主线程ID<br>} PROCESS_INFORMATION;<br><br>另外还有一个关键的结构 STARTUPINFO,该结构定义如下:<br><br>typedef struct STARTUPINFO { <br>DWORD cb; //结构长度<br>LPTSTR lpReserved; //保留<br>LPTSTR lpDesktop; //保留<br>LPTSTR lpTitle; //如果为控制台进程则为显示的标题<br>DWORD dwX; //窗口位置<br>DWORD dwY; //窗口位置<br>DWORD dwXSize; //窗口大小<br>DWORD dwYSize; //窗口大小<br>DWORD dwXCountChars; //控制台窗口字符号宽度<br>DWORD dwYCountChars; //控制台窗口字符号高度<br>DWORD dwFillAttribute; //控制台窗口填充模式<br>DWORD dwFlags; //创建标记<br>WORD wShowWindow; //窗口显示标记,如同ShowWindow中的标记<br>WORD cbReserved2; //<br>LPBYTE lpReserved2; //<br>HANDLE hStdInput; //标准输入句柄<br>HANDLE hStdOutput; //标准输出句柄<br>HANDLE hStdError; //标准错误句柄<br>} STARTUPINFO, *LPSTARTUPINFO;<br><br>结构中 dwFlags 指定了其它的一些字段是否有效,如:dwFlags包含 STARTF_USESIZE 表示dwXSize和dwYSize有效,包含STARTF_USEPOSITION表示dwX和dwY有效,等等。如果不是有特殊的要求,我们不用自己去填写这个结构,只需用 GetStartupInfo 让 Windows 为你填写好了,这样,建立一个进程的语句就是:<br><br>...<br>stStartUp STARTUPINFO stProcInfo PROCESS_INFORMATION &lt;?&gt; <br>stProcInfo PROCESS_INFORMATION &lt;?&gt;<br>... <br><br>invoke GetStartupInfo,addr stStartUp<br>invoke CreateProcess,NULL,addr szFileName,NULL,NULL,NULL,NORMAL_PRIORITY_CLASS,NULL,NULL,offset stStartUp,offset stProcInfo<br>... <br><br>如果成功的话,eax 将返回非零值,注意返回在 PROCESS_INFORMATION 结构中的 hProcess,以后很多的操作都要用到它。<br><br>强制结束一个进程的 API 为 TerminateProcess<br><br><br>BOOL TerminateProcess(<br>HANDLE hProcess, // 进程句柄<br>UINT uExitCode // 退出代码 <br>);<br><br>你可以使用语句 invoke TerminateProcess,structProcInfo.hProcess,0 来结束进程,要注意的是如果可能的话,尽量不要在程序中强制结束别的进程,因为使用 TerminateProcess 结束的进程,它装载的 dll 不能被正确卸载。这样可能会引起系统资源的无效占用。最好的办法在进程中自己使用 ExitProcess 退出。<br><br>查询一个进程状态的 API 为 GetExitCodeProcess。<br><br>BOOL GetExitCodeProcess(<br>HANDLE hProcess, // handle to the process <br>LPDWORD lpExitCode // address to receive termination status <br>);<br><br>如果进程尚未退出,函数将会返回STILL_ACTIVE。这个 API 是马上返回的。<br><br>等待进程执行可以用 WaitForSingleObject<br><br>这个 API 并不是单用于进程的等待,其它还可以用在线程等操作,但我们一般用它来等待进程的执行,它的申明是:<br><br>DWORD WaitForSingleObject(<br>HANDLE hHandle, // handle of object to wait for<br>DWORD dwMilliseconds // time-out interval in milliseconds <br>);<br><br>如果我们要等待进程执行 1 秒钟,可以 invoke WaitForSingleObject,stProcInfo.hProcess,1000 如果要等到进程结束,可以用 WaitForSingleObject,stProcInfo.hProcess,INFINITE ,参数 2 中的 INFINITE 在 Windows.inc 中有定义,意思是无穷等待。 <br><br>最后,当不再使用进程句柄的时候,不要忘了使用 CloseHandle 关闭 hProcess 和 hThread,否则会浪费系统句柄的资源<br>
 
参数很简单呀,Filename-执行文件名,Params-执行文件的参数,WindowState-可以是以下<br>这些:<br>SW_NORMAL;<br>SW_HIDE;<br>什么的,你看看winexec的参数帮助就知道了<br>
 
多人接受答案了。
 
顶部