VC+中進程與多進程管理的方法_第1頁
VC+中進程與多進程管理的方法_第2頁
VC+中進程與多進程管理的方法_第3頁
VC+中進程與多進程管理的方法_第4頁
VC+中進程與多進程管理的方法_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、VC+中進程與多進程管理的方法進程是當前操作系統(tǒng)下一個被加載到內存的、正在運行的應用程序的實例。每一個進程都是由內核對象和地址空間所組成的,內核對象可以讓系統(tǒng)在其內存放有關進程的統(tǒng)計信息并使系統(tǒng)能夠以此來管理進程,而地址空間則包括了所有程序模塊的代碼和數(shù)據(jù)以及線程堆棧、堆分配空間等動態(tài)分配的空間。進程僅僅是一個存在,是不能獨自完成任何操作的,必須擁有至少一個在其環(huán)境下運行的線程,并由其負責執(zhí)行在進程地址空間內的代碼。在進程啟動的同時即同時啟動了一個線程,該線程被稱作主線程或是執(zhí)行線程,由此線程可以繼續(xù)創(chuàng)建子線程。如果主線程退出,那么進程也就沒有存在的可能了,系統(tǒng)將自動撤消該進程并完成對其地址空

2、間的釋放。加載到進程地址空間的每一個可執(zhí)行文件或動態(tài)鏈接庫文件的映象都會被分配一個與之相關聯(lián)的全局唯一的實例句柄(Hinstance)。該實例句柄實際是一個記錄有進程加載位置的基本內存地址。進程的實例句柄在程序入口函數(shù)WinMain()中通過第一個參數(shù)HINSTANCE hinstExe傳遞,其實際值即為進程所使用的基本地址空間的地址。對于VC+鏈接程序所鏈接產(chǎn)生的程序,其默認的基本地址空間地址為0x,如沒有必要一般不要修改該值。在程序中,可以通過GetModuleHandle()函數(shù)得到指定模塊所使用的基本地址空間。子進程的創(chuàng)建進程的創(chuàng)建通過CreateProcess()函數(shù)來實現(xiàn),Crea

3、teProcess()通過創(chuàng)建一個新的進程及在其地址空間內運行的主線程來啟動并運行一個新的程序。具體的,在執(zhí)行CreateProcess()函數(shù)時,首先由操作系統(tǒng)負責創(chuàng)建一個進程內核對象,初始化計數(shù)為1,并立即為新進程創(chuàng)建一塊虛擬地址空間。隨后將可執(zhí)行文件或其他任何必要的動態(tài)鏈接庫文件的代碼和數(shù)據(jù)裝載到該地址空間中。在創(chuàng)建主線程時,也是首先由系統(tǒng)負責創(chuàng)建一個線程內核對象,并初始化為1。最后啟動主線程并執(zhí)行進程的入口函數(shù)WinMain(),完成對進程和執(zhí)行線程的創(chuàng)建。CreateProcess()函數(shù)的原型聲明如下:BOOL CreateProcess(LPCTSTR lpApplication

4、Name, / 可執(zhí)行模塊名LPTSTR lpCommandLine, / 命令行字符串LPSECURITY_ATTRIBUTES lpProcessAttributes, / 進程的安全屬性LPSECURITY_ATTRIBUTES lpThreadAttributes, / 線程的安全屬性BOOL bInheritHandles, / 句柄繼承標志DWORD dwCreationFlags, / 創(chuàng)建標志LPVOID lpEnvironment, / 指向新的環(huán)境塊的指針LPCTSTR lpCurrentDirectory, / 指向當前目錄名的指針LPSTARTUPINFO lpStar

5、tupInfo, / 指向啟動信息結構的指針LPPROCESS_INFORMATION lpProcessInformation / 指向進程信息結構的指針); 在程序設計時,某一個具體的功能模塊可以通過函數(shù)或是線程等不同的形式來實現(xiàn)。對于同一進程而言,這些函數(shù)、線程都是存在于同一個地址空間下的,而且在執(zhí)行時,大多只對與其相關的一些數(shù)據(jù)進行處理。如果算法存在某種錯誤,將有可能破壞與其同處一個地址空間的其他一些重要內容,這將造成比較嚴重的后果。為保護地址空間中的內容可以考慮將那些需要對地址空間中的數(shù)據(jù)進行訪問的操作部分放到另外一個進程的地址空間中運行,并且只允許其訪問原進程地址空間中的相關數(shù)據(jù)。

6、具體的,可在進程中通過CreateProcess()函數(shù)去創(chuàng)建一個子進程,子進程在全部處理過程中只對父進程地址空間中的相關數(shù)據(jù)進行訪問,從而可以保護父進程地址空間中與當前子進程執(zhí)行任務無關的全部數(shù)據(jù)。對于這種情況,子進程所體現(xiàn)出來的作用同函數(shù)和線程比較相似,可以看成是父進程在運行期間的一個過程。為此,需要由父進程來掌握子進程的啟動、執(zhí)行和退出。下面這段代碼即展示了此過程:/ 臨時變量CString sCommandLine;char cWindowsDirectoryMAX_PATH;char cCommandLineMAX_PATH;DWORD dwExitCode;PROCESS_INFO

7、RMATION pi;STARTUPINFO si = sizeof(si);/ 得到Windows目錄GetWindowsDirectory(cWindowsDirectory, MAX_PATH);/ 啟動記事本程序的命令行sCommandLine = CString(cWindowsDirectory) + NotePad.exe;:strcpy(cCommandLine, sCommandLine);/ 啟動記事本作為子進程BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si

8、, &pi);if (ret) / 關閉子進程的主線程句柄CloseHandle(pi.hThread);/ 等待子進程的退出WaitForSingleObject(pi.hProcess, INFINITE);/ 獲取子進程的退出碼GetExitCodeProcess(pi.hProcess, &dwExitCode);/ 關閉子進程句柄CloseHandle(pi.hProcess); 此段代碼首先通過CreateProcess()創(chuàng)建Windows自帶的“記事本”程序為子進程,子進程啟動后父進程通過WaitForSingleObject()函數(shù)等待其執(zhí)行的結束,在子進程沒有退出前父進程是

9、一直處于阻塞狀態(tài)的,這里子進程的作用同單線程中的函數(shù)類似。一旦子進程退出,WaitForSingleObject()函數(shù)所等待的pi.hProcess對象將得到通知,父進程將得以繼續(xù),如有必要可以通過GetExitCodeProcess()來獲取子進程的退出代碼。相比而言,更多的情況是父進程在啟動完子進程后就再不與其進行任何數(shù)據(jù)交換和通訊,由其創(chuàng)建的子進程的執(zhí)行成功與否均與父進程無關。許多大型軟件在設計時也多采用了這類思想,將某些功能完全通過獨立的應用程序來完成,當需要執(zhí)行某操作時只要通過主程序啟動相應的子進程即可,具體的處理工作均由子進程去完成。這類子進程的創(chuàng)建過程更為簡單,例如對于上面那段

10、代碼只需去除對子進程句柄pi.hProcess的等待即可:BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);if (ret) / 關閉子進程的主線程句柄CloseHandle(pi.hThread);/ 關閉子進程句柄CloseHandle(pi.hProcess); 可以通過dwCreationFlags參數(shù)在創(chuàng)建進程時設置子進程的優(yōu)先級。前面的示例代碼在創(chuàng)建子進程時使用的均是默認的優(yōu)先級,如果要將優(yōu)先級設置為高,可以修改如下:BOOL ret = CreatePr

11、ocess(NULL, cCommandLine, NULL, NULL, FALSE, HIGH_PRIORITY_CLASS, NULL, NULL, &si, &pi); 如果在進程創(chuàng)建時沒有特別設置優(yōu)先級,可以通過SetPriorityClass()函數(shù)來動態(tài)設定,該函數(shù)需要待操作進程的句柄和優(yōu)先級標識符作為入口參數(shù),函數(shù)原型為:BOOL SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass); 對于前面沒有設定優(yōu)先級的例子代碼,可以在子進程啟動后由父進程來動態(tài)改變其優(yōu)先級設置:SetPriorityClass(pi.hProc

12、ess, HIGH_PRIORITY_CLASS); 或是由子進程在其啟動后自行改變優(yōu)先級設置,需要注意的是這時進程句柄應設置為子進程自身的句柄,可通過GetCurrentProcess()函數(shù)來獲?。篐ANDLE hProcess = GetCurrentProcess();SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS); 進程的互斥運行正常情況下,一個進程的運行一般是不會影響到其他正在運行的進程的。但是對于某些有特殊要求的如以獨占方式使用串行口等硬件設備的程序就要求在其進程運行期間不允許其他試圖使用此端口設備的程序運行的,而且此類程序通常也不

13、允許運行同一個程序的多個實例。這就引出了進程互斥的問題。實現(xiàn)進程互斥的核心思想比較簡單:進程在啟動時首先檢查當前系統(tǒng)是否已經(jīng)存在有此進程的實例,如果沒有,進程將成功創(chuàng)建并設置標識實例已經(jīng)存在的標記。此后再創(chuàng)建進程時將會通過該標記而知曉其實例已經(jīng)存在,從而保證進程在系統(tǒng)中只能存在一個實例。具體可以采取內存映射文件、有名事件量、有名互斥量以及全局共享變量等多種方法來實現(xiàn)。下面就分別對其中具有代表性的有名互斥量和全局共享變量這兩種方法進行介紹:/ 創(chuàng)建互斥量HANDLE m_hMutex = CreateMutex(NULL, FALSE, Sample07);/ 檢查錯誤代碼if (GetLast

14、Error() = ERROR_ALREADY_EXISTS) / 如果已有互斥量存在則釋放句柄并復位互斥量CloseHandle(m_hMutex);m_hMutex = NULL;/ 程序退出return FALSE; 上面這段代碼演示了有名互斥量在進程互斥中的用法。代碼的核心是CreateMutex()對有名互斥量的創(chuàng)建。CreateMutex()函數(shù)可用來創(chuàng)建一個有名或無名的互斥量對象,其函數(shù)原型為:HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, / 指向安全屬性的指針BOOL bInitialOwner, / 初

15、始化互斥對象的所有者LPCTSTR lpName / 指向互斥對象名的指針); 如果函數(shù)成功執(zhí)行,將返回一個互斥量對象的句柄。如果在CreateMutex()執(zhí)行前已經(jīng)存在有相同名字的互斥量,函數(shù)將返回這個已經(jīng)存在互斥量的句柄,并且可以通過GetLastError()得到錯誤代碼ERROR_ALREADY_EXIST??梢?,通過對錯誤代碼ERROR_ALREADY_EXIST的檢測可以實現(xiàn)CreateMutex()對進程的互斥。使用全局共享變量的方法則主要是在MFC框架程序中通過編譯器來實現(xiàn)的。通過#pragma data_seg預編譯指令創(chuàng)建一個新節(jié),在此節(jié)中可用volatile關鍵字定義一

16、個變量,而且必須對其進行初始化。Volatile關鍵字指定了變量可以為外部進程訪問。最后,為了使該變量能夠在進程互斥過程中發(fā)揮作用,還要將其設置為共享變量,同時允許具有讀、寫訪問權限。這可以通過#pragma comment預編譯指令來通知編譯器。下面給出使用了全局變量的進程互斥代碼清單:#pragma data_seg(Shared) int volatile g_lAppInstance =0;#pragma data_seg()#pragma comment(linker,/section:Shared,RWS)if(+g_lAppInstance1)return FALSE; 此段代碼

17、的作用是在進程啟動時對全局共享變量g_nAppInstancd 加1 ,如果發(fā)現(xiàn)其值大于1,那么就返回FALSE以通知進程結束。這里需要特別指出的是,為了使以上兩段代碼能夠真正起到對進程互斥的作用,必須將其放置在應用程序的入口代碼處,即應用程序類的初始化實例函數(shù)InitInstance()的開始處。結束進程進程只是提供了一段地址空間和內核對象,其運行是通過在其地址空間內的主線程來體現(xiàn)的。當主線程的進入點函數(shù)返回時,進程也就隨之結束。這種進程的終止方式是進程的正常退出,進程中的所有線程資源都能夠得到正確的清除。除了這種進程的正常推出方式外,有時還需要在程序中通過代碼來強制結束本進程或其他進程的運

18、行。ExitProcess()函數(shù)即可在進程中的某個線程中使用,并將立即終止本進程的運行。ExitProcess()函數(shù)原型為:VOID ExitProcess(UINT uExitCode); 其參數(shù)uExitCode為進程設置了退出代碼。該函數(shù)具有強制性,在執(zhí)行完畢后進程即已經(jīng)被結束,因此位于其后的任何代碼將不能被執(zhí)行。雖然ExitProcess()函數(shù)可以在結束進程的同時通知與其相關聯(lián)的動態(tài)鏈接庫,但是由于它的這種執(zhí)行的強制性,使得ExitProcess()函數(shù)在使用上將存在有安全隱患。例如,如果在程序調用ExitProcess()函數(shù)之前曾用new操作符申請過一段內存,那么將會由于Ex

19、itProcess()函數(shù)的強制性而無法通過delete操作符將其釋放,從而造成內存泄漏。有鑒于ExitProcess()函數(shù)的強制性和不安全性,在使用時一定要引起注意。ExitProcess()只能強制執(zhí)行本進程的退出,如果要在一個進程中強制結束其他的進程就要用TerminateProcess()來實現(xiàn)。與ExitProcess()不同,TerminateProcess()函數(shù)執(zhí)行后,被終止的進程是不會得到任何關于程序退出的通知的。也就是說,被終止的進程是無法在結束運行前進行退出前的收尾工作的。所以,通常只有在其他任何方法都無法迫使進程退出時才會考慮使用TerminateProcess()去

20、強制結束進程的。下面給出TerminateProcess()的函數(shù)原型:BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode); 參數(shù)hProcess和uExitCode分別為進程句柄和退出代碼。如果被結束的是本進程,可以通過GetCurrentProcess()獲取到句柄。TerminateProcess()是異步執(zhí)行的,在調用返回后并不能確定被終止進程是否已經(jīng)真的退出,如果調用TerminateProcess()的進程對此細節(jié)關心,可以通過WaitForSingleObject()來等待進程的真正結束。小結多進程是多任務管理中的重要內容

21、,文中上述部分對其基本概念和主要的技術如子進程的創(chuàng)建與結束、進程間的互斥運行等做了較詳細的介紹。通過本文讀者應能對多進程管理有一個初步的認識。 進程控制簡單的說相當于在一個程序中執(zhí)行另一個程序,你可以把它想象成在 Dos 下用 int 21h/4bh 功能來執(zhí)行另外一個程序,如果單從執(zhí)行另一個程序的目的來講,在 Windows 中有不少方法,如使用 ShellExecute 等,但這些 Api 僅僅是“執(zhí)行”而已,進程控制的意義在于可以創(chuàng)建一個進程,并可以通過進程句柄結束進程,同樣你也可以通過進程句柄來跟蹤程序,還可以用 ReadProcessMemory 和 WriteProcessMemo

22、ry 來讀寫子進程的內存空間。進程控制要使用的相關 API 有下面這些:創(chuàng)建進程的函數(shù)為CreateProcess,該函數(shù)比較復雜,共有十個參數(shù),但有個好消息是使用時大部分可以用 NULL。BOOL CreateProcess( LPCTSTR lpApplicationName, / 執(zhí)行程序文件名LPTSTR lpCommandLine, / 參數(shù)行 LPSECURITY_ATTRIBUTES lpProcessAttributes, / 進程安全參數(shù)LPSECURITY_ATTRIBUTES lpThreadAttributes, / 線程安全參數(shù)BOOL bInheritHandles

23、, / 繼承標記DWORD dwCreationFlags, / 創(chuàng)建標記LPVOID lpEnvironment, / 環(huán)境變量LPCTSTR lpCurrentDirectory, / 運行該子進程的初始目錄LPSTARTUPINFO lpStartupInfo, / 創(chuàng)建該子進程的相關參數(shù) LPPROCESS_INFORMATION lpProcessInformation / 創(chuàng)建后用于被創(chuàng)建子進程的信息);各個參數(shù)的說明如下:lpApplicationName:為執(zhí)行程序的文件名,你也可以把執(zhí)行文件名包括在下一個參數(shù) lpCommandLine 中,然后把該參數(shù)置為NULL。lpCo

24、mmandLine:為參數(shù)行,如果無參數(shù)可以為NULL,在有參數(shù)傳遞給進程時可以如下設置:lpApplicationName=文件名;lpCommandLine=參數(shù),或者 lpApplicationName=NULL;lpCommandLine=文件名 + 參數(shù)。lpProcessAttributes,lpThreadAttributes:分別描述了創(chuàng)建的進程和線程安全屬性,如果使用NULL表示使用默認的安全描述。bInheritHandles:表示當前進程中的打開的句柄是否能夠被創(chuàng)建的子進程所繼承。dwCreationFlags:表示創(chuàng)建標記,通過該標記可以設置進程的創(chuàng)建狀態(tài)和優(yōu)先級別。常

25、用的有下面的標記: CREATE_NEW_CONSOLE:為子進程創(chuàng)建一個新的控制臺。 CREATE_SUSPENDED:子進程在創(chuàng)建時為掛起狀態(tài)。如果指定了這個參數(shù),那么執(zhí)行 CreateProcess 后進程只是被裝入內存,但不是馬上開始執(zhí)行,而是必須等主程序調用 ResumeThread 后才繼續(xù)執(zhí)行。HIGH_PRIORITY_CLASS/NORMAL_PRIORITY_CLASS:高/普通優(yōu)先級別。lpEnvironment:表示子進程所使用的環(huán)境變量,如果為NULL,則表示與當前進程使用相同的環(huán)境變量。lpCurrentDirectory:表示子進程運行的初始目錄。lpStartu

26、pInfo:STARTUPINFO 結構,用于在創(chuàng)建子進程時設置各種屬性。lpProcessInformation:PROCESS_INFORMATION 結構,用來在進程創(chuàng)建后接收相關信息,該結構由系統(tǒng)填寫。調用 CreateProcess 函數(shù)有三個參數(shù)是必需的,一在 lpApplicationName 或 lpCommandLine 指定文件名,二是 lpStartupInfo 結構,三是 PROCESS_INFORMATION 結構,因為 PROCESS_INFORMATION 結構返回了進程建立后的句柄,以后的一切操作將要用到這些返回的句柄,它是由系統(tǒng)填寫的,結構說明如下:typed

27、ef struct _PROCESS_INFORMATION HANDLE hProcess; /進程句柄HANDLE hThread; /進程的主線程句柄DWORD dwProcessId; /進程IDDWORD dwThreadId; /進程的主線程ID PROCESS_INFORMATION;另外還有一個關鍵的結構 STARTUPINFO,該結構定義如下:typedef struct STARTUPINFO DWORD cb; /結構長度LPTSTR lpReserved; /保留LPTSTR lpDesktop; /保留LPTSTR lpTitle; /如果為控制臺進程則為顯示的標題D

28、WORD dwX; /窗口位置DWORD dwY; /窗口位置DWORD dwXSize; /窗口大小DWORD dwYSize; /窗口大小DWORD dwXCountChars; /控制臺窗口字符號寬度DWORD dwYCountChars; /控制臺窗口字符號高度DWORD dwFillAttribute; /控制臺窗口填充模式DWORD dwFlags; /創(chuàng)建標記WORD wShowWindow; /窗口顯示標記,如同ShowWindow中的標記WORD cbReserved2; /LPBYTE lpReserved2; /HANDLE hStdInput; /標準輸入句柄HANDL

29、E hStdOutput; /標準輸出句柄HANDLE hStdError; /標準錯誤句柄 STARTUPINFO, *LPSTARTUPINFO;結構中 dwFlags 指定了其它的一些字段是否有效,如:dwFlags包含 STARTF_USESIZE 表示dwXSize和dwYSize有效,包含STARTF_USEPOSITION表示dwX和dwY有效,等等。如果不是有特殊的要求,我們不用自己去填寫這個結構,只需用 GetStartupInfo 讓 Windows 為你填寫好了,這樣,建立一個進程的語句就是:.stStartUp STARTUPINFO stProcInfo PROCES

30、S_INFORMATION stProcInfo PROCESS_INFORMATION .invoke GetStartupInfo,addr stStartUpinvoke CreateProcess,NULL,addr szFileName,NULL,NULL,NULL,NORMAL_PRIORITY_CLASS,NULL,NULL,offset stStartUp,offset stProcInfo.如果成功的話,eax 將返回非零值,注意返回在 PROCESS_INFORMATION 結構中的 hProcess,以后很多的操作都要用到它。強制結束一個進程的 API 為 Termina

31、teProcessBOOL TerminateProcess(HANDLE hProcess, / 進程句柄UINT uExitCode / 退出代碼 );你可以使用語句 invoke TerminateProcess,structProcInfo.hProcess,0 來結束進程,要注意的是如果可能的話,盡量不要在程序中強制結束別的進程,因為使用 TerminateProcess 結束的進程,它裝載的 dll 不能被正確卸載。這樣可能會引起系統(tǒng)資源的無效占用。最好的辦法在進程中自己使用 ExitProcess 退出。查詢一個進程狀態(tài)的 API 為 GetExitCodeProcess。BOO

32、L GetExitCodeProcess(HANDLE hProcess, / handle to the process LPDWORD lpExitCode / address to receive termination status );如果進程尚未退出,函數(shù)將會返回STILL_ACTIVE。這個 API 是馬上返回的。等待進程執(zhí)行可以用 WaitForSingleObject這個 API 并不是單用于進程的等待,其它還可以用在線程等操作,但我們一般用它來等待進程的執(zhí)行,它的申明是:DWORD WaitForSingleObject(HANDLE hHandle, / handle o

33、f object to wait forDWORD dwMilliseconds / time-out interval in milliseconds );如果我們要等待進程執(zhí)行 1 秒鐘,可以 invoke WaitForSingleObject,stProcInfo.hProcess,1000 如果要等到進程結束,可以用 WaitForSingleObject,stProcInfo.hProcess,INFINITE ,參數(shù) 2 中的 INFINITE 在 Windows.inc 中有定義,意思是無窮等待。最后,當不再使用進程句柄的時候,不要忘了使用 CloseHandle 關閉 hPr

34、ocess 和 hThread,否則會浪費系統(tǒng)句柄的資源。源程序 - 匯編源文件 .386 .model flat, stdcall option casemap :none ; case sensitive; Include 數(shù)據(jù);include windows.incinclude user32.incinclude kernel32.incinclude comctl32.incinclude comdlg32.incinclude gdi32.incincludelib user32.libincludelib kernel32.libincludelib comctl32.libin

35、cludelib comdlg32.libincludelib gdi32.lib; Equ 數(shù)據(jù);DLG_MAIN equ 3000;ID_BROWSE equ 3001ID_RUN equ 3002ID_EXIT equ 3003ID_TEXT equ 3004F_RUNNING equ 0001h ;進程在運行中; 數(shù)據(jù)段; .data?stStartUp STARTUPINFO stProcInfo PROCESS_INFORMATION stOpenFileName OPENFILENAME hRunThread dd ?hInstance dd ?hWinMain dd ?hIco

36、n dd ?szBuffer db 512 dup (?)dwFlag dd ?; .dataszExcute db 執(zhí)行(&E),0 ;按鈕文字szKill db 終止(&E),0szExcuteError db 啟動應用程序錯誤!,0szTitleOpen db Open executable file.,0szExt db *.exe,0szFilter db Excutable Files,0,*.exe;*.com,0 db 0; 代碼段; .codeif DEBUG include Debug.asmendifinclude Win.asm;*; 執(zhí)行程序用的線程; 1. 用 Cr

37、eateProcess 建立進程; 2. 用 WaitForSingleOject 等待進程結束;*_RunThread proc uses ebx ecx edx esi edi, dwParam:DWORD or dwFlag,F_RUNNING;*; 取消“退出”按鈕并把“執(zhí)行”按鈕改為“中止”;* invoke GetDlgItem,hWinMain,ID_EXIT invoke EnableWindow,eax,FALSE invoke SendDlgItemMessage,hWinMain,ID_RUN,WM_SETTEXT,0,offset szKill;*; 執(zhí)行文件,如果成功

38、則等待程序結束;* invoke GetStartupInfo,addr stStartUp invoke CreateProcess,NULL,addr szBuffer,NULL,NULL, NULL,NORMAL_PRIORITY_CLASS,NULL,NULL,offset stStartUp,offset stProcInfo .if eax != 0 invoke WaitForSingleObject,stProcInfo.hProcess,INFINITE invoke CloseHandle,stProcInfo.hProcess invoke CloseHandle,stP

39、rocInfo.hThread .else invoke MessageBox,hWinMain,addr szExcuteError,NULL,MB_OK or MB_ICONERROR .endif;*; Enable “退出”按鈕并把“中止”按鈕改為“執(zhí)行”;* invoke GetDlgItem,hWinMain,ID_EXIT invoke EnableWindow,eax,TRUE invoke SendDlgItemMessage,hWinMain,ID_RUN,WM_SETTEXT,0,offset szExcute and dwFlag,not F_RUNNING ret_R

40、unThread endp;*; 窗口程序;*DialogMainProc proc uses ebx edi esi, hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,wMsg;* .if eax = WM_INITDIALOG mov eax,hWnd mov hWinMain,eax call _Init;* .elseif eax = WM_CLOSE invoke EndDialog,hWinMain,NULL;* .elseif eax = WM_COMMAND mov eax,wParam .if ax = ID_B

41、ROWSE call _BrowseFile call _CheckText .elseif ax = ID_TEXT invoke GetDlgItemText,hWinMain,ID_TEXT,addr szBuffer,512 call _CheckText .elseif ax = ID_RUN;*; 如果沒有在執(zhí)行中(dwFlag 沒有置位) 則建立線程,在線程中執(zhí)行程序; 如果已經(jīng)在執(zhí)行中,則用 TerminateProcess 終止執(zhí)行;* test dwFlag,F_RUNNING .if ZERO? invoke CreateThread,NULL,NULL,offset _

42、RunThread, NULL,NULL,offset hRunThread .else invoke TerminateProcess,stProcInfo.hProcess,-1 .endif .elseif ax = ID_EXIT invoke EndDialog,hWinMain,NULL .endif .else;*; 注意:對話框的消息處理后,要返回 TRUE,對沒有處理的消息; 要返回 FALSE;* mov eax,FALSE ret .endif mov eax,TRUE retDialogMainProc endp;*; 程序入口;*start: invoke InitCommonControls invoke GetModuleHandle,NULL mov hInstance,eax invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset DialogMainProc,0 invoke ExitProcess

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論