zoukankan      html  css  js  c++  java
  • 跟我一起玩Win32开发(17):启动和结束进程

    这里我再次说明一下,我不知道为什么,现在的人那么喜欢走极端,估计是价值观都“升级”了的缘故吧。

    我撰写这一系列Win32相关的文章,并不是叫大家一定要用Win32去开发项目,仅仅是给大家了解一下,Win32是个啥东西而已。

    另外,在专访中,有些人也误认为我说C++非学不可,那也不是,我也提到过了,C++的学习可以使你懂得更多知识,为你以为学习各种技术打下基础。

    今天,我们来了解一下,在应用程序中,如何启动一个进程,然后把这个进程结束掉。实现这一功能有替代方案,即使用.NET库中的System::Diagnostics::Process类来完成。在Win32中,启动一个进程可以理解为创建进程,所以可以调用CreateProcess函数,结束进程则调用TerminateProcess函数。

    唯一标识一个进程的是PID,而我们要对进程进行各项操作,进程也存在于内存中,也可以视为一种资源,我们知识,操作图标资源有HICON,操作位图资源有HBITMAP,同样道理,对进程所作的操作也要通过一个标识符(句柄)——HANDLE。

    CreateProcess函数的最后一个参数是一个指向PROCESS_INFORMATION结构体的指针,该结构的成员可以保存被创建进程的ID和句柄。

    [cpp] view plain copy
     
    1. typedef struct _PROCESS_INFORMATION {  
    2.     HANDLE hProcess; //进程的句柄  
    3.     HANDLE hThread; //主线程的句柄  
    4.     DWORD dwProcessId; //进程ID  
    5.     DWORD dwThreadId; //主线程ID  
    6. } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;  

    接下来我们要对已创建进程进行的一系列操作,都以hProcess为纽带,包括获取退出码和终止进程。

    CreateProcess函数的最后两个参数都是指针,因此我们在使用时,要先定义STARTUPINFO和PROCESS_INFORMATION类型的变量,并使用ZeroMemory函数将其成员初始化。ZeroMemory函数可以将一段内存中的数据初始化为0.

    示例代码如下:

    [cpp] view plain copy
     
    1. PROCESS_INFORMATION pro_info; //进程信息  
    2. STARTUPINFO sti; //启动信息  
    3. //......  
    4. // 初始化两个结构体  
    5. ZeroMemory(&pro_info, sizeof(PROCESS_INFORMATION));  
    6. ZeroMemory(&sti, sizeof(STARTUPINFO));  


    接着调用CreateProcess创建进程.

    [cpp] view plain copy
     
    1. CreateProcess(L"C:\Windows\System32\calc.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&sti,&pro_info);  

    调用成功后,PROCESS_INFORMATION结构体的hProcess就保存了被创建的进程的句柄了。

    要结束进程,调用TerminateProcess函数,第一个参数就是刚才创建的时程的句柄,第二个参数是退出码,通过GetExitCodeProcess函数可以获取。

    [cpp] view plain copy
     
    1. DWORD exitCode; //退出码  
    2. //.........  
    3. GetExitCodeProcess(pro_info.hProcess,&exitCode); //获取退出码  
    4. TerminateProcess(pro_info.hProcess, exitCode);  
    5. // 关闭句柄  
    6. CloseHandle(pro_info.hThread);  
    7. CloseHandle(pro_info.hProcess);  


    下面是这个示例的运行结果图,完整的代码我稍后上传到资源区中。


    另外,再介绍一个在应用程序中运行其他程序的方法,那就是使用Shell函数——ShellExecute。

    [cpp] view plain copy
     
    1. HINSTANCE ShellExecute(  
    2.   _In_opt_  HWND hwnd,  
    3.   _In_opt_  LPCTSTR lpOperation,  
    4.   _In_      LPCTSTR lpFile,  
    5.   _In_opt_  LPCTSTR lpParameters,  
    6.   _In_opt_  LPCTSTR lpDirectory,  
    7.   _In_      INT nShowCmd  
    8. );  

    我们这里只是运行一个程序,没有其他操作,所以,带 _In_opt_的可选参数可以直接NULL,lpFile指定我们要运行程序的路径,如果是一个exe文件,那lpParameters可以指定命令行参数,但我们这里不需要,所以继续NULL,最后一个参数好理解,和ShowWindow函数一样。

    于是,用ShellExecute函数打开记事本程序,当然记得包含shellapi.h。

    [cpp] view plain copy
     
    1. ShellExecute(NULL,NULL,L"C:\Windows\System32\notepad.exe",NULL,NULL,SW_SHOWNORMAL);  

    看看结果,和前面效果差不多。



    源代码稍后上传。

     
     
     
    lxtx6905
     
    c10682
    • c10682

      2013-03-05 13:25#4楼
    • 这个进程控制,用 AAuto 非常方便

      XP自动玩扫雷
      [javascript] view plain copy
       
      1. import process;  
      2. import winex;  
      3.     
      4. var DATABASE = 0x1005340 //棋盘基址  
      5. var SETBASE = 0x01005330 //设置基址+0:雷点个数 +4:棋盘宽 +8:棋盘高  
      6. var XYBASE = 0x01005118 //call参数:XYBASE:x   XYBASE+4:y  
      7.    
      8. var prc = process("winmine.exe") //创建扫雷进程   
      9. var act = prc.remoteApi("void()", 0x010037E1);  //获取远程call  
      10.    
      11. var width = prc.readNumber(SETBASE+4,"INT")  
      12. var height = prc.readNumber(SETBASE+8,"INT")  
      13. for(j=1;height) {  
      14.   
      15.     for(i=1;width) {  
      16.         n = prc.readNumber(DATABASE+i+32*j,"byte")  //棋盘基址+x+y*32=棋盘点的值  
      17.         /* 
      18.         n:棋盘点的值 
      19.         未点击时:无雷:0f;;;有雷,8f (有用) 
      20.         点击后:无雷:4x,x=周围雷的个数;;;有雷8x 
      21.         */  
      22.         if(n==0x0f) {   
      23.             prc.writeNumber(XYBASE,i,"INT")  //写X坐标  
      24.             prc.writeNumber(XYBASE+4,j,"INT")  //写Y坐标  
      25.             act();   
      26.         }  
      27.     }  
      28. }  
  • 相关阅读:
    操作系统的运行机制
    操作系统的目标和功能
    操作系统的特征
    操作系统的基本概念
    error: a label can only be part of a statement and a declaration is not a statement
    克隆git仓库中的一个分支
    ubuntu下update-alternatives命令的使用
    堆排序
    合并排序
    递归算法的一些规则
  • 原文地址:https://www.cnblogs.com/weekbo/p/8681926.html
Copyright © 2011-2022 走看看