<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 一、前言 進程是計算機中運行的程序,是向操作系統申請資源的基本單位。我們運行一個程序,那么就會相應地創建一個甚至多個進程,關閉程序時,進程也就結束了。查看進程最常用的手段是按下Ctrl+Shift+Delete打開Windows自帶的任務管理器,或者使用老牌強力軟件“冰刃”,又或者是使用由微軟推出的更為強大的Process Monitor,都能基本得到相同的效果。不同的是,強大的進程查看軟件能夠查看到系統的隱藏進程,而一般的只能查看應用層的進程。而我在這兩篇文章中所討論的就是如何實現一個簡易的進程管理器,通過它可以管理當前的進程,也可以管理進程所加載的DLL。這篇文章主要討論的就是進程管理方面的編程,下一篇再討論DLL管理方面的程序編寫。 ## 二、界面設計 本程序需要設計兩個界面,這篇文章只討論第一個界面的制作。這里需要一個“List Control”和三個“Button”控件: ![](https://box.kancloud.cn/2016-02-18_56c57429cd41b.jpg) 圖1 主界面的設計 然后設置“List Control”的控件屬性,在“Sytles”中的“View”中,選擇“Report”,再選中“Single Selection”選項。然后為其添加一個名為“m_ProcessList”的變量,然后通過編程進行初始化: ~~~ void CProcessManageDlg::InitProcessList() { //設置“List Control”控件的擴展風格 m_ProcessList.SetExtendedStyle( m_ProcessList.GetExtendedStyle() | LVS_EX_GRIDLINES //有網絡格 | LVS_EX_FULLROWSELECT); //選中某行使整行高亮(只適用于report風格) //添加列目 m_ProcessList.InsertColumn(0, _T("序號")); m_ProcessList.InsertColumn(1, _T("進程名稱 ")); m_ProcessList.InsertColumn(2, _T("PID值")); m_ProcessList.InsertColumn(3, _T("線程數")); m_ProcessList.InsertColumn(4, _T("父進程ID")); m_ProcessList.InsertColumn(5, _T("線程優先級")); //設置列的寬度 m_ProcessList.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER); m_ProcessList.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER); m_ProcessList.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER); m_ProcessList.SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER); m_ProcessList.SetColumnWidth(4, LVSCW_AUTOSIZE_USEHEADER); m_ProcessList.SetColumnWidth(5, LVSCW_AUTOSIZE_USEHEADER); } ~~~ 之后在CProcessManageDlg::OnInitDialog()中添加: ~~~ InitProcessList(); ~~~ 以實現初始化,再在頭文件中聲明: ~~~ void InitProcessList(); ~~~ ## 三、進程的枚舉 進程的枚舉就是把所有的進程顯示出來,而有一些特意隱藏的進程是無法通過常規的枚舉方式枚舉到的。這里所講解的是應用層的進程枚舉。為實現此功能,這里使用的是CreateToolhelp32Snapshot()。它的作用是對當前系統中的進程進行一個快照,在創建成功后對進程逐個枚舉。枚舉進程需要用到Process32First()以及Process32Next()這兩個函數。使用這幾個函數需要先包含Tlhelp32.h頭文件。代碼如下: ~~~ void CProcessManageDlg::ShowProcess() { //清空列表 m_ProcessList.DeleteAllItems(); //給系統內所有的進程拍個快照 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if ( hSnap == INVALID_HANDLE_VALUE ) { AfxMessageBox("進程快照創建失敗!"); return ; } PROCESSENTRY32 Pe32 = { 0 }; //在使用這個結構前,先設置它的大小 Pe32.dwSize = sizeof(PROCESSENTRY32); //遍歷進程快照,輪流顯示每個進程的信息 BOOL bRet = Process32First(hSnap, &Pe32); int i = 0; CString str; while ( bRet ) { str.Format("%d", i); m_ProcessList.InsertItem(i, str); //進程名 m_ProcessList.SetItemText(i, 1, Pe32.szExeFile); //進程ID str.Format("%d", Pe32.th32ProcessID); m_ProcessList.SetItemText(i, 2, str); //此進程開啟的線程計數 str.Format("%d", Pe32.cntThreads); m_ProcessList.SetItemText(i, 3, str); //父進程ID str.Format("%d", Pe32.th32ParentProcessID); m_ProcessList.SetItemText(i, 4, str); //線程優先權 str.Format("%d", Pe32.pcPriClassBase); m_ProcessList.SetItemText(i, 5, str); i ++; bRet = Process32Next(hSnap, &Pe32); } CloseHandle(hSnap); } ~~~ 因為我希望剛打開程序,就能夠把系統的進程顯示出來,因此要在OnInitDialog()中添加: ~~~ ShowProcess(); ~~~ 最后在頭文件中加上: ~~~ void ShowProcess(); ~~~ ## 四、結束進程 通常情況下,進程正常結束時,會調用ExitProcess()函數來使自身退出。而如果想要結束指定的進程,則需要使用TerminateProcess()函數。但是對于進程的操作,往往都需要使用其PID值,為了方便起見,這里編寫一個獲取進程PID值的程序,以方便接下來對于進程的一系列操作。它的原理就是在進程被枚舉出來,顯示在列表框中以后,返回所選取進程的“PID值”的內容: ~~~ int CProcessManageDlg::GetSelectPid() { pid = -1; //獲取列表框中所選中的位置 POSITION Pos = m_ProcessList.GetFirstSelectedItemPosition(); int nSelect = -1; while ( Pos ) { nSelect = m_ProcessList.GetNextSelectedItem(Pos); } //如果在列表框中沒有進行選擇,則報錯 if ( -1 == nSelect ) { AfxMessageBox("請選擇進程!"); return -1; } //獲取列表框中顯示的PID值 char szPid[10] = { 0 }; m_ProcessList.GetItemText(nSelect, 2, szPid, 10); pid = atoi(szPid); return pid; } ~~~ 這個函數需要在頭文件中聲明: ~~~ int GetSelectPid(); ~~~ 然后為“結束進程”按鈕添加代碼: ~~~ void CProcessManageDlg::OnButtonTerminate() { // TODO: Add your control notification handler code here int nPid = GetSelectPid(); HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, nPid); TerminateProcess(hProcess, 0); CloseHandle(hProcess); ShowProcess(); } ~~~ 上述代碼的原理是先獲取進程的權限,然后再進行結束。 ## 五、暫停與恢復進程 有些時候,惡意程序為了保護自身,可能會創建兩個或者多個進程,令其“榮辱與共”。當其中一個進程發現另一個進程被結束了,那么它就會把那個被結束的進程重新運行起來。這幾個進程相互幫助,所以就很難把惡意程序的進程徹底結束掉,也就不能刪除惡意程序本身。遇到這種情況,可以將這幾個進程暫停,然后就可以結束掉惡意進程了。 暫停進程通常使用的是SuspendThread()函數,它需要使用線程的句柄,線程的句柄可以通過OpenThread()函數獲得,然后利用Thread32First()以及Thread32Next()這兩個函數進行枚舉。為“暫停進程”按鈕添加代碼: ~~~ void CProcessManageDlg::OnBtnStop() { // TODO: Add your control notification handler code here int nPid = -1; nPid = GetSelectPid(); //創建線程快照 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, nPid); if ( hSnap == INVALID_HANDLE_VALUE ) { AfxMessageBox("暫停進程失敗!"); return ; } THREADENTRY32 Te32 = { 0 }; Te32.dwSize = sizeof(THREADENTRY32); BOOL bRet = Thread32First(hSnap, &Te32); while ( bRet ) { //判斷線程所屬 if ( Te32.th32OwnerProcessID == nPid ) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, Te32.th32ThreadID); SuspendThread(hThread); CloseHandle(hThread); } bRet = Thread32Next(hSnap, &Te32); } } ~~~ 由于CreateToolhelp32Snapshot()只能創建系統的線程快照,不能創建指定進程中的線程的快照。所以如果想要暫停線程,必須對枚舉到的線程進行判斷,看其是否為指定進程中的線程。在THREADENTRY32這個結構體中的th32ThreadID標識了當前枚舉到的線程的線程ID,而th32OwnerProcessID標識了該線程歸屬的進程的ID。所以在上述代碼中需要進行判斷,以找到相應的線程。 接下來為“恢復進程”按鈕添加代碼: ~~~ void CProcessManageDlg::OnButtonResume() { // TODO: Add your control notification handler code here int nPid = -1; nPid = GetSelectPid(); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, nPid); if ( hSnap == INVALID_HANDLE_VALUE ) { AfxMessageBox("進程恢復失敗!"); return ; } THREADENTRY32 Te32 = { 0 }; Te32.dwSize = sizeof(THREADENTRY32); BOOL bRet = Thread32First(hSnap, &Te32); while ( bRet ) { if ( Te32.th32OwnerProcessID == nPid ) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, Te32.th32ThreadID); ResumeThread(hThread); CloseHandle(hThread); } bRet = Thread32Next(hSnap, &Te32); } } ~~~ 因為它與暫停進程原理相同,不再贅述。 ## 六、程序效果 上述程序編譯成功后,就能夠對進程實現結束、暫停與恢復的效果。 ![](https://box.kancloud.cn/2016-02-18_56c5742a04280.jpg) 圖2 查看記事本進程 比如對一個“記事本”程序做實驗。打開記事本,運行本軟件,找到記事本的進程,單擊“暫停進程”按鈕,可見雖然記事本程序仍可見,但是已無法對其操作。直至單擊“恢復進程”后,記事本才又恢復原樣。然后單擊“結束進程”,則記事本就被關閉,它已經從列表框中消失了。說明我們的程序是有效的。 **** ## 七、小結 這次實現了一個簡單的進程管理器程序,這類程序往往在手動查殺病毒方面有很大的用處。也希望讀者能夠舉一反三,在這個基礎上開發出功能更加全面的程序出來。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看