WINDOWS编程-进程(Process)

一.什么为进程

进程实体的执行过程叫做进程,通俗的话来讲就是在磁盘上的程序被双击运行起来后,就称为进程。

每个进程中都含有一个主线程,用来真正执行程序。进程是空间的概念,线程是时间的概念。

二.进程的创建过程

打开系统--->双击要运行的程序--->EXE开始执行

步骤一:
当系统启动后,创建一个进程:Explorer.exe也就是桌面进程

步骤二:

当用户双击某个EXE时,Explorer.exe使用CreateProcess()API为该EXE创建进程,即在桌面上双击创建的进程,他们的父进程都是Explorer.exe

 

  • 创建内核对象

用户层                                                                       内核层(高2G的内存,每个进程有2^32=4GB的内存空间,低2G由ring3使用,高2G由ring0使用)

CreateProcess                                          NtCreateProcess

                      WINDOWS编程-进程(Process)          句柄表,刚创建的时候为空

 

 

                      如果这个刚刚被创建的进程,里面的线程用创建了其他的内核对象

 

                                       WINDOWS编程-进程(Process) 内核对象的句柄表,为了安全,不会给客户端返回真正的地址,而是一个编号

 

  • 分配4GB的虚拟空间(windows 32位)

WINDOWS编程-进程(Process)

 

 

 

  • 创建进程的主线程

当进程的空间创建完毕,EXE与导入表中的DLL都正确加载完毕后,会创建一个线程

当线程得到CPU的时候,程序就正开始指向了,EIP的初始值设定为:ImageBase+OEP

当进程创建成功后,会将进程句柄、主线程句柄、进程ID以及主线程ID存储在

 

typedef struct _PROCESS_INFORMATION                    
{                    
   HANDLE hProcess;                //进程句柄    
   HANDLE hThread;                //主线程句柄    
   DWORD dwProcessId;                //进程ID    
   DWORD dwThreadId;                //线程ID    
} PROCESS_INFORMATION;                    

 

也就是,CreateProcess的最后一个 OUT 参数。到此,整个进程创建结束了

 

 

三.CreateProcess()API

 


BOOL CreateProcess( LPCTSTR lpApplicationName,
// name of executable module LPTSTR lpCommandLine, // command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD BOOL bInheritHandles, // handle inheritance option DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // new environment block LPCTSTR lpCurrentDirectory, // current directory name LPSTARTUPINFO lpStartupInfo, // startup information LPPROCESS_INFORMATION lpProcessInformation // process information

 

 

四.创建进程的几种方式

VOID TestCreateProcessByAPPName()                    
{                    
    STARTUPINFO si = {0};                   
        PROCESS_INFORMATION pi;                
                    
    si.cb = sizeof(si);                
                    
    TCHAR szApplicationName[] =TEXT("c://program files//internet explorer//iexplore.exe");                
                    
    BOOL res = CreateProcess(                
        szApplicationName,             
        NULL,             
        NULL,             
        NULL,             
        FALSE,             
        CREATE_NEW_CONSOLE,             
        NULL,             
        NULL, &si, &pi);             
                       
}                    
VOID TestCreateProcessByCmdline()                    
{                    
    STARTUPINFO si = {0};                   
        PROCESS_INFORMATION pi;                
                    
    si.cb = sizeof(si);                
                    
    TCHAR szCmdline[] =TEXT("c://program files//internet explorer//iexplore.exe http://www.ifeng.com");                
                    
    BOOL res = CreateProcess(                
        NULL,             
        szCmdline,             
        NULL,             
        NULL,             
        FALSE,             
        CREATE_NEW_CONSOLE,             
        NULL,             
        NULL, &si, &pi);             
}                    
VOID TestCreateProcess()                    
{                    
    STARTUPINFO si = {0};                   
        PROCESS_INFORMATION pi;                
                    
    si.cb = sizeof(si);                
                    
    TCHAR szCmdline[] =TEXT(" http://www.ifeng.com");                
                    
    BOOL res = CreateProcess(                
        TEXT("c://program files//internet explorer//iexplore.exe"),             
        szCmdline,             
        NULL,             
        NULL,             
        FALSE,             
        CREATE_NEW_CONSOLE,             
        NULL,             
        NULL, &si, &pi);             
}                    
typedef struct _STARTUPINFO                    
{                    
   DWORD cb;                    
   PSTR lpReserved;                    
   PSTR lpDesktop;                    
   PSTR lpTitle;                    
   DWORD dwX;                    
   DWORD dwY;                    
   DWORD dwXSize;                    
   DWORD dwYSize;                    
   DWORD dwXCountChars;                    
   DWORD dwYCountChars;                    
   DWORD dwFillAttribute;                    
   DWORD dwFlags;                    
   WORD wShowWindow;                    
   WORD cbReserved2;                    
   PBYTE lpReserved2;                    
   HANDLE hStdInput;                    
   HANDLE hStdOutput;                    
   HANDLE hStdError;                    
} STARTUPINFO, *LPSTARTUPINFO;                    
                    
                    
用来设定要创建的应用程序的属性,比如可以指定新创建的控制台程序的标题等待。                    
                    
一般情况,只要为第一个成员赋值就可以了.                    
                    
si.cb = sizeof(si);                     
typedef struct _PROCESS_INFORMATION                    
{                    
   HANDLE hProcess;                //进程句柄    
   HANDLE hThread;                //主线程句柄    
   DWORD dwProcessId;                //进程ID    
   DWORD dwThreadId;                //线程ID    
} PROCESS_INFORMATION;                    

五.关于句柄和ID

1、都是系统分配的一个编号,句柄是客户程序使用 ID主要是系统调度时使用.

2、调用CloseHandle关闭进程或者线程句柄的时候,只是让内核计数器(GetTickCount)减少一个,并不是终止进程或者线程.
进程或线程将继续运行,直到它自己终止运行。

3、进程ID与线程ID 是不可能相同。但不要通过进程或者线程的ID来操作进程或者线程,因为,这个编号是会
重复使用的,也就是说,当你通过ID=100这个编号去访问一个进程的时候,它已经结束了,而且系统将这个编号
赋给了另外一个进程或者线程.

六.终止进程的三种方式

1、VOID ExitProcess(UINT fuExitCode) //进程自己调用

2、BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode); //终止其他进程

3、ExitThread //终止进程中的所有线程,进程也会终止


获取进程的退出码:

BOOL GetExitCodeProcess(HANDLE hProcess,PDWORD pdwExitCode);

进程终止时相关操作:

1、进程中剩余的所有线程全部终止运行

2、进程指定的所有用户对象均被释放,所有  内核对象均被关闭

3、进程内核对象的状态变成收到通知的状态

4、进程内核对象的使用计数递减1

 

 

WINDOWS编程-进程(Process)

上一篇:保存windows 10的登录界面壁纸


下一篇:C# 图片上传问题