Windows 2000系统编程——进程的创建( 三 )


① 调用 GetExitCodeProcess
命令 GetExitCodeProcess 既能返回 STILL_ACTIVE , 也能返回进程退出值(如果进程结束时)返回值需要一个指针 , 其指向命令填充的变量 。
② 调用 WaitForSingleObject
WaitForSingleObject 的目的是要确定句柄是否处于发送信号的状态 。当进程结束时 , 进程句柄发出信号 。当调用 WaitForSingleObject 时 , 就规定进程句柄和超时值 , 如果超时为 0 , 则该命令就立刻返回 , 且能够确定进程的状态 。如果超时是常数 INFINITE , 则命令就不返回 , 直到目标进程退出为止 。当然 , 还可以规定超时值 , 其导致该命令等待要结束的进程一段时间 。如果进程在超时届满前结束 , 该命令就返回 , 并指出句柄在发射信号状态 。否则 , 就返回一个负值 。不管句柄在何种状态 , WaitForSingleObject 将成功返回 , 没有错误发生 。要确定进程的状态 , 就必须比较返回值为 WAIT_OBJECT_0 (已发信号的)和 WAIT_TIMEOUT (未发信号的) 。真正的错误返回值为 WAIT_FAILED。另外可能的返回值是 WAIT_ABANDONED , 是不会看到何时处理进程 。要等待一个进程 , 就必须带有 SYNCHRONIZE 特权的打开局柄 。
这里要注意 , 进程 ID 与进程句柄不同 。不能简单地在进程之间传送句柄 , 这意味着除非有句柄 , 否则不能从外部进程直接操纵一个进程 。不过 OpenProcess 命令将允许任何程序(有足够的安全特权)将进程标示符(可以用来于其它进程通信)变换为进程句柄 。通过调用 GetCurrentProcessId , 还可以了解当前进程标示符 。如果要想与其他无关的进程共享 , 以使能够打开进程句柄 , 这是非常有用的 。但调用 OpenProcess 时 , 可以请求对进程的访问 。对每种进程的访问 , 也许有或也许没有访问要打开进程的安全性 , 于是试图请求是仅仅需要的 。例如 , 如果要了解进程的返回代码 , 就需要 PROCESS_QUERY_INFORMATION 的访问 。要终止进程 , 就必须有 PROCESS_TERMINATE 的访问 。
⑸ 程序示例
下面通过一个例子来说名 CreateProcess 和相关命令的使用 。下面程序是两个简单的控制台应用程序 , 第一个程序( MASTER )运行第二个程序( SLAVE ) , 并进入睡眠 。SLAVE 程序从命令行读取源程序的进程 ID(PID), 并等待 MASTER 程序终止 。这些程序说明了以下几个重要技术:
l 使用 CreateProcess
l 使用 OpenProcess
l 使用 WaitForSingleObject
程序清单 MASTER 程序
#include
#include
#include
#include
void main(int argc,char *argv[])
{
char cmd[128];
if (argc!=1)
strcpy(cmd,argv[1]);
else
strcpy(cmd,”slave.exe”);
int pid=GetCurrentProcessId();
sprintf(cmd strlen(cmd),” %d”,pid);
cout<<”Master: Starting:”< cout.flush();
STARTUPINFO info;
memset(&info,0,sizeof(info));
info.cb=sizeof(info);
PROCESS_INFORMATION pinfo;
If(!CreateProcess(NULL,cmd,NULL,NULL,FALSE{
c out<<”Master:Slave process did not startn”;
c out<<” Master:Try naming slave process on the command linen”;
}
cout<<”Master:Sleepingn”;
cout.flush();
Sleep(15000);
Cout<<”Master:Exitingn”;
exit(0);
}
程序清单 SLAVE 程序
#include
#include
#include
void main(int argc,char *argv[])
{
if (argc!=2)
{
cout<<”Slave:Please rrun MASTER.EXE instead.n”;
exit(1);
}
int pid=atoi(argv[1]);
HANDLE process=OpenProcess(PROCESS_QUERY_INFORMATION|SYNCHRONIZE,FALSE,pid);
if (!process) cot<<”Slave:Error opening processn”;
cout<<”Slave :Waiting for master to finishn”;

推荐阅读