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函式返回