📄 teach_sp_42.htm
字号:
<!-- LANGUAGE='JavaScript'>write_body();<-->
<!-- LANGUAGE='JavaScript'>write_bar();<-->
<table width=98% cellspacing="0" cellpadding="0" align=center><!--整体框架-->
<tr><td>
<table border=0 width="100%" cellspacing="0" cellpadding="2"><!--标记放置区域-->
<tr>
<td width="30%" align="center" bgcolor="#8E8E8E" valign=middle><img src=../../img/brand_200_60.gif width=200 height=60 alt="LOGO1"></td>
<td width="70%" align="center" bgcolor="#8E8E8E" valign=middle><!-- LANGUAGE='JavaScript'>write_ban();<--></td>
</tr>
<tr>
<td colspan="2" bgcolor="#939393" align=center><font color=white>您当前位置</font> <a href=../../index.htm><font color=white>首页</font></a> <a href=../index.htm><font color=white>开发教程</font></a> <a href=index.htm><font color=white><font class=engul>Visual C++/MFC</font>专题讲座</font></a> <font color=white>4.2 进程控制</font> <font color=white><!-- LANGUAGE='JavaScript'>write_command();<--></font></td>
</tr>
</table><!--标记放置区域 END-->
<table border=0 width=100% cellspacing="0" cellpadding="0">
<tr bgcolor="#F4F4F4">
<td><!-- article title begin here-->
<br>
<p align=center><big>4.2 进程控制
</big></p>
<!-- article content begin here-->
<table border=0 align=center width=100%>
<tr><td>
<small>
<p>进程控制的意义在于可以创建一个进程,并可以通过进程句柄结束进程。
<p>创建进程的函数为CreateProcess,该函数比较复杂共有十个参数。
<pre><b>BOOL CreateProcess(
LPCTSTR</b><i> lpApplicationName</i><b>,</b><b> </b>// 执行程序文件名
<b> LPTSTR</b><i> lpCommandLine</i><b>, </b>// 参数行
<b> LPSECURITY_ATTRIBUTES</b><i> lpProcessAttributes</i><b>, </b>// 进程安全参数
<b> LPSECURITY_ATTRIBUTES</b><i> lpThreadAttributes</i><b>, </b>// 线程安全参数
<b> BOOL</b><i> bInheritHandles</i><b>, </b>// 继承标记
<b> DWORD</b><i> dwCreationFlags</i><b>, </b>// 创建标记
<b> LPVOID</b><i> lpEnvironment</i><b>, </b>// 环境变量
<b> LPCTSTR</b><i> lpCurrentDirectory</i><b>, </b>// 运行该子进程的初始目录
<b> LPSTARTUPINFO</b><i> lpStartupInfo</i><b>, </b>// 创建该子进程的相关参数
<b> LPPROCESS_INFORMATION</b><i> lpProcessInformation</i> // 创建后用于被创建子进程的信息
<b>);</b></pre>
<p>lpApplicationName:为执行程序的文件名,如果在创建进程时要使用参数,则该参数可以为NULL。</p>
<p>lpCommandLine:为参数行,如果无参数可以为NULL,在有参数传递给进程时如下设置:lpApplicationName=NULL;lpCommandLine=para,例如lpCommandLine="c:\\windows\\notepad.exe
c:\\autoexec.bat"。 </p>
<p>lpProcessAttributes,lpThreadAttributes<b>:</b>分别描述了创建的进程和线程安全属性,如果使用NULL表示使用默认的安全描述。</p>
<p>bInheritHandles:表示当前进程中的打开的句柄是否能够被创建的子进程所继承。</p>
<p>dwCreationFlags:表示创建标记,通过该标记可以设置进程的创建状态和优先级别。常用的有下面的标记:</p>
<ul>
<li>CREATE_NEW_CONSOLE:为子进程创建一个新的控制台。</li>
<li>CREATE_SUSPENDED:子进程在创建时为挂起状态。</li>
<li>HIGH_PRIORITY_CLASS/NORMAL_PRIORITY_CLASS:高/普通优先级别。</li>
</ul>
<p>lpEnvironment:表示子进程所使用的环境变量,如果为NULL,则表示与当前进程使用相同的环境变量。</p>
<p>lpCurrentDirectory:表示子进程运行的初始目录。</p>
<p>lpStartupInfo:用于在创建子进程时设置各种属性。该结构定义如下:</p>
<pre>typedef struct _STARTUPINFO { // si
DWORD cb; //结构长度
LPTSTR lpReserved; //保留
LPTSTR lpDesktop; //保留
LPTSTR lpTitle; //如果为控制台进程则为显示的标题
DWORD dwX; //窗口位置
DWORD dwY; //窗口位置
DWORD dwXSize; //窗口大小
DWORD dwYSize; //窗口大小
DWORD dwXCountChars; //控制台窗口字符号宽度
DWORD dwYCountChars; //控制台窗口字符号高度
DWORD dwFillAttribute; //控制台窗口填充模式
DWORD dwFlags; //创建标记
WORD wShowWindow; //窗口显示标记如同ShowWindow中的标记
WORD cbReserved2; //
LPBYTE lpReserved2; //
HANDLE hStdInput; //标准输入句柄
HANDLE hStdOutput; //标准输出句柄
HANDLE hStdError; //标准错误句柄
} STARTUPINFO, *LPSTARTUPINFO;
</pre>
<p>如果要使结构中相关的分量起作用,必须正确的设置dwFlags。例如:dwFlags包含STARTF_USESIZE表示dwXSize和dwYSize有效,包含STARTF_USEPOSITION表示dwX和dwY有效。</p>
<p>lpProcessInformation:用来在进程创建后接收相关信息,该结构由系统填写。</p>
<pre>typedef struct _PROCESS_INFORMATION { // pi
HANDLE hProcess; //进程句柄
HANDLE hThread; //进程的主线程句柄
DWORD dwProcessId; //进程ID
DWORD dwThreadId; //进程的主线程ID
} PROCESS_INFORMATION; </pre>
<p>在本节提供的例子中使用下面的代码创建新进程:</p>
<pre>
PROCESS_INFORMATION pi;
STARTUPINFO si;
si.cb=sizeof(si);
si.wShowWindow=SW_SHOW;
si.dwFlags=STARTF_USESHOWWINDOW;
BOOL fRet=CreateProcess(NULL,
"c:\\windows\\notepad.exe c:\\autoexec.bat",
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
if(success)
{
m_hPro=pi.hProcess;//保存当前进程句柄,在强制结束进程时使用。
}
</pre>
<p>如果要结束进程需要知道进程的句柄,在上面的例子中我们已经保存了pi.hProcess。</p>
<p>结束一个进程所使用的函数为:</p>
<pre><b>BOOL TerminateProcess(
HANDLE</b><i> hProcess</i><b>, </b>// 进程句柄
<b> UINT</b><i> uExitCode</i> // 退出代码
<b>);</b>
</pre>
<p>本节的例子中使用下面的代码来结束进程。</p>
<pre>
if(m_hPro)
{
if(!TerminateProcess(m_hPro,0)) //结束代码为0
{
reportError(...);
}
else
{
AfxMessageBox("TerminateProcess成功");
}
m_hPro=NULL;
}
else
{
AfxMessageBox("m_hPro为空");
}
</pre>
<p>在进程内结束进程的方法为调用:VOID ExitProcess( UINT uExitCode )建议在进程内部进行退出,因为进程被强制结束时可能一些DLL不能被正确卸载。</p>
<p>退出代码可以在其他进程中通过调用GetExitCodeProcess获得。</p>
<pre><b>BOOL GetExitCodeProcess(
HANDLE</b><i> hProcess</i><b>, </b>// handle to the process
<b> LPDWORD</b><i> lpExitCode</i> // address to receive termination status
<b>);</b>
</pre>
<p>如果进程尚未退出,函数将会返回STILL_ACTIVE。</p>
<p>在以前的Windows3.X时代,我们使用</p>
<pre><b>UINT WinExec(
LPCSTR</b><i> lpCmdLine</i><b>, </b>// 命令行
<b> UINT</b><i> uCmdShow</i> // 窗口显示方式
<b>);</b> </pre>
<p>现在仍然可以使用这个函数但我们可以看到我们在运行程序后无法得到该程序的各种句柄。所以建议使用CreateProcess创建进程。</p>
<p><a href="sam_sp_42.zip">下载本节代码</a></p>
<p align=center><a href=index.htm#charpter4>返回</a></p>
</small>
</td></tr><!-- article content end-->
</table>
<p align=center><small>版权所有 闻怡洋 <a href=http://www.vchelp.net/><font class=engul>http://www.vchelp.net/<font></font></font></a></small></p>
</td>
</tr><!-- article title end-->
</table>
</td></tr></table><!--整体框架 END-->
<!-- LANGUAGE='JavaScript'>write_tail();<-->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -