Windows核心编程——进程的基本概念以及创建和退出

一、什么是进程

  进程是资源分配的基本单位,也是独立运行的基本单位。通俗讲就是一段程序执行的过程。

  进程由两部分构成,一部分指一个内核对象,操作系统用它来管理进程,也是系统保存进程统计信息的地方。

  令一部分由地址空间构成,包括文本区、数据区、堆栈区。文本区存储处理器执行的代码,数据区存储变量和进程执行期间使用的的动态内存分配,堆栈区存储活动过程中调用的指令和本地变量

二、进程的三种基本状态

进程在运行过程中不断改变其运行状态,通常情况下,一个运行进程必须具有以下三种状态

1)就绪(Ready):当进程分配到除了CPU以外的所有的必要资源,只要处理器分配资源就能马上执行,这时的状态就称为就绪状态。

2)运行(Running):当进程已经获得处理器的资源分配,进程正在运行,此时的进程状态称为运行状态

3)阻塞(Blockjer):正在执行的进程,由于等待某个事件发生而无法执行时,便放弃资源分配而处于阻塞状态,例如等待I/O完成,申请缓冲区不能满足,等待信号等。

三、进程的创建和退出

Windows下常见创建进程的方法:

1)Winexec

2)ShellExcute

3)CreateProcess

1.Winexec

UINT WinExec(  
LPCSTR lpCmdLine,  // 路径名(可以带cmd命令行)
 UINT uCmdShow      // 显示状态);

   

PS:如果lpCmdLine参数中可执行文件的名称不包含目录路径,则系统将按以下顺序搜索可执行文件的路径:

    1.加载应用程序的目录。
    2.当前目录。
    3.Windows系统目录。GetSystemDirectory函数检索此目录的路径。
    4.Windows目录。GetWindowsDirectory函数检索此目录的路径。
    5.PATH环境变量中列出的目录。


示例:

在对话框添加一个测试按钮,添加事件:
打开一个进程:

UINT nRet = ::WinExec(
    "C:\\Users\\shadow\\Desktop\\depends.exe",  // 路径名
    SW_SHOW     // 显示状态
);

还可以打开cmd(包括带参启动):
带参启动cmd:
    /k 并显示控制台窗口
    /c  执行命令并关闭控制台窗口
   

 打开注册表:

UINT nRet = ::WinExec("cmd.exe /c regedit", SW_SHOW);


    改uac权限:

UINT nRet = ::WinExec("cmd /k %windir%\\System32\\reg.exe ADD HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System /v EnableLUA /t REG_DWORD /d 0 /f",SW_SHOW);

 

2.ShellExcute

 API函数:

     HINSTANCE ShellExecute(
           HWND hwnd,   //指定窗口的句柄
           LPCTSTR lpOperation, //指定要进行的操作
           LPCTSTR lpFile,   
               LPCTSTR lpParameters,  //若lpFile是可执行文件,则此参数指定命令行参数
           LPCTSTR lpDirectory,   //指定默认目录
           INT nShowCmd  //指定程序窗口初始化显示方式
        );


示例:

ShellExecute(NULL,  "open","C:\\Users\\shadow\\Desktop\\depends.exe",NULL, NULL,SW_SHOWNORMAL); 
//打开进程 ShellExecute(NULL, "open", "www.baidu.com/s?wd=\"拼音\"", NULL, NULL,SW_SHOW); //打开网址 ShellExecute(NULL, "explore", "D:\\360", NULL, NULL, SW_SHOWNORMAL); //打开文件夹 ShellExecute(NULL, "print", "C:\\Users\\shadow\\Desktop\\t.txt", NULL, NULL, SW_HIDE);
//打印机 ShellExecute(NULL, "open", "cmd.exe", "/k dir", NULL, SW_SHOWNORMAL); //自动搜索路径

 
打开exe:

STARTUPINFO si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };
TCHAR szCmdLine[] = {L"cmd.exe /k ping www.baidu.com"};
BOOL bRet = ::CreateProcess(
    NULL, //exe的路径
    szCmdLine, //命令行参数
    NULL,
    NULL,
    FALSE,
    0,    //没有别的需求,创建标志填0
    NULL, //环境块
    NULL, //当前目录
    &si, //启动进程一些配置
    &pi);

3.CreateProcess

API函数:

BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
); 

 
参数详解:https://blog.csdn.net/baidu_29198395/article/detai
ls/82926348

示例:

void CProcessDlg::OnBnClickedButton3()
{
    STARTUPINFO si = { 0 };
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi = { 0 };

    BOOL bRet = ::CreateProcess(
        "C:\\Users\\shadow\\Desktop\\depends.exe",
        NULL, //命令行参数
        NULL,
        NULL,
        FALSE,
        0,    //没有别的需求,创建标志填0
        NULL, //环境块
        NULL, //当前目录
        &si, //启动进程一些配置
        &pi
    );

    if (!bRet)
    {
        AfxMessageBox(_T("进程启动失败, 请调试"));
    }

}


注意:
lpStartupInfo
cb
必须初始化为sizeof(STARTUPINFO),或sizeof*STARTUOINFOEX

四.退出进程

    1) ExitProcess(0);
  执行后直接退出进程,后边代码将无法执行

    2)TerminateProcess (不推荐使用,因为目标进程没有机会清理资源)

    3)进程中的所有线程自行终止运行(这种情况几乎从未发生)
    
    4)  主线程的进入点函数返回(最好使用这个方法),main函数返回





猜你喜欢

转载自www.cnblogs.com/zhaoyixiang/p/12984903.html