1. 程式人生 > WINDOWS開發 >Windows核心程式設計——程序的基本概念以及建立和退出

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,SW_SHOWNORMAL); 
//開啟程序 ShellExecute(NULL,"www.baidu.com/s?wd=\"拼音\"",SW_SHOW); //開啟網址 ShellExecute(NULL,"explore","D:\\360",SW_SHOWNORMAL); //開啟資料夾 ShellExecute(NULL,"print","C:\\Users\\shadow\\Desktop\\t.txt",SW_HIDE);
//印表機 ShellExecute(NULL,"cmd.exe","/k dir",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,FALSE,//沒有別的需求,建立標誌填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,//沒有別的需求,建立標誌填0
        NULL,//環境塊
        NULL,//當前目錄
        &si,//啟動程序一些配置
        &pi
    );

    if (!bRet)
    {
        AfxMessageBox(_T("程序啟動失敗, 請除錯"));
    }

}


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

四.退出程序

1) ExitProcess(0);
  執行後直接退出程序,後邊程式碼將無法執行

2)TerminateProcess (不推薦使用,因為目標程序沒有機會清理資源)

3)程序中的所有執行緒自行終止執行(這種情況幾乎從未發生)

4) 主執行緒的進入點函式返回(最好使用這個方法),main函式返回