摘 要:本文介紹了自動(dòng)安裝程序?qū)崿F(xiàn)原理和方法。主要介紹了自解壓軟件包程序在完成解壓任務(wù)之后,如何自動(dòng)完成安裝軟件的任務(wù),包括如何等待子進(jìn)程setup.exe、判斷setup.exe已經(jīng)完成安裝,然后刪除臨時(shí)文件的方法和過程。
關(guān)鍵詞:自解壓;安裝程序
中圖分類號(hào):TP311.52
假如有一個(gè)程序要調(diào)用一個(gè)setup.exe程序,自動(dòng)安裝一個(gè)軟件,完成安裝后再把臨時(shí)文件和臨時(shí)目錄全部刪除,應(yīng)怎樣實(shí)現(xiàn)呢?要實(shí)現(xiàn)自解壓包將包中的壓縮文件釋放完成后,自動(dòng)啟動(dòng)setup.exe安裝程序很簡單,但是完成安裝后要?jiǎng)h除先前釋放的臨時(shí)文件卻稍有麻煩。關(guān)鍵問題就是必須先判斷安裝程序已經(jīng)完成了安裝,然后才能刪除。因?yàn)槿绻谶€沒有完成安裝的時(shí)候刪除臨時(shí)文件和文件夾,可能會(huì)導(dǎo)致兩個(gè)嚴(yán)重后果:第一是安裝失敗,第二是某些文件無法刪除(這時(shí)它還在內(nèi)存里)。
那么,如何判斷何時(shí)安裝程序已經(jīng)完成了安裝任務(wù)呢?當(dāng)然可以用while(GetExitCodeProcess(newinfo.hProcess,dwExitCode)dwExitCode==STILL_ACTIVE);來等待setup.exe運(yùn)行結(jié)束。但是問題可能并不這么簡單,常常是setup.exe又調(diào)用了別的子進(jìn)程(例如_delis和inst5176什么的),而setup.exe退出后,子進(jìn)程并未退出,即安裝任務(wù)仍未完成。早期的WinRAR(2.50版)創(chuàng)建的TempMode自解壓文件,在自動(dòng)啟動(dòng)setup.exe后安裝過程之所以會(huì)失敗,我判斷可能就是因?yàn)榕袛噱e(cuò)誤,即在未完成安裝時(shí)就把臨時(shí)文件刪除了。由此看來不應(yīng)把setup.exe的退出作為安裝任務(wù)完成的標(biāo)志,而應(yīng)以是否存在臨時(shí)目錄下的任何程序仍處于執(zhí)行狀態(tài),作為判斷依據(jù)。即如果存在這樣的進(jìn)程,則安裝仍未完成,反之則安裝已經(jīng)完成。下面把筆者的實(shí)現(xiàn)思路介紹如下,供感興趣的同行參考。
1 解決步驟
以下把setup.exe叫做安裝程序,把我的程序叫做自動(dòng)安裝程序。
現(xiàn)在假設(shè)自動(dòng)安裝程序已經(jīng)將臨時(shí)文件釋放到臨時(shí)文件夾,然后可以按照如下步驟來判斷何時(shí)安裝程序已經(jīng)完成了安裝任務(wù):
1.1 創(chuàng)建一個(gè)事件。即用系統(tǒng)函數(shù)CreateEvent()創(chuàng)建一個(gè)事件hEvent;
hEvent=::CreateEvent(
NULL, // SD
FALSE, // reset type
FALSE, // initial state
NULL // object name
);
以便于自動(dòng)安裝程序等待安裝任務(wù)的完成。
1.2 啟動(dòng)安裝程序。啟動(dòng)釋放在臨時(shí)目錄(比如C:\WINDOWS\TEMP\MYTEMP)下的安裝程序setup.exe:
strcpy(sTemFile,sPath);strcat(sTemFile,\"\\Setup.exe\");
::CreateProcess(sTemFile,NULL,NULL,NULL,F(xiàn)ALSE,
CREATE_DEFAULT_ERROR_MODE|CREATE_NO_WINDOW,
NULL,sPath,info,newinfo);
其中sPath中的內(nèi)容就是臨時(shí)目錄的路徑。
1.3 讓自動(dòng)安裝程序循環(huán)等待。執(zhí)行如下語句讓自動(dòng)安裝程序處于循環(huán)等待狀態(tài):
::ResetEvent(hEvent);
while(::WaitForSingleObject(hEvent,500)==WAIT_TIMEOUT)
{ IsExit();}
應(yīng)當(dāng)先將事件hEvent復(fù)位到無信號(hào)狀態(tài)。IsExit()函數(shù)的功能就是判斷當(dāng)前是否有安裝程序進(jìn)程及其子進(jìn)程存在,若有則表明安裝過程仍在進(jìn)行,若沒有則安裝已經(jīng)完成。當(dāng)安裝已經(jīng)完成時(shí)函數(shù)IsExit()將事件hEvent置為有信號(hào)狀態(tài),從而結(jié)束循環(huán)等待。IsExit()函數(shù)的實(shí)現(xiàn)后面再單獨(dú)介紹。
1.4 關(guān)閉事件句柄、刪除臨時(shí)文件和文件夾。::CloseHandle(hEvent);RemoveThem(sPath);
其中sPath表示臨時(shí)目錄路徑,而函數(shù)RemoveThem()的作用是刪除以sPath為根的子目錄樹,限于篇幅這里將實(shí)現(xiàn)過程略去。
2 IsExit()函數(shù)的實(shí)現(xiàn)
主要是通過調(diào)用CreateToolhelp32Snapshot()、Process32First()和Process32Next()這三個(gè)系統(tǒng)函數(shù),通過列舉系統(tǒng)中進(jìn)程,來判斷安裝過程是否完成。在調(diào)用列舉進(jìn)程的函數(shù)時(shí)必須添加#include
2.1 調(diào)用系統(tǒng)函數(shù)CreateToolhelp32Snapshot()。在CreateToolhelp32Snapshot中()指定TH32CS_SNAPPROCESS參數(shù),獲取系統(tǒng)中所有進(jìn)程的列表(snapshot):
HANDLE hSnapshot;PROCESSENTRY32 pe;
pe.dwSize=sizeof(pe);BOOL blExist=FALSE;
size_t len=strlen(sPath);
hSnapshot=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hSnapshot<0) goto L1;
2.2 調(diào)用系統(tǒng)函數(shù)Process32First()。調(diào)用系統(tǒng)函數(shù)Process32First()獲取第一個(gè)進(jìn)程的信息:
if(::Process32First(hSnapshot,pe)==FALSE)
{
::CloseHandle(hSnapshot); goto L1;
}
if(_strnicmp(sPath,pe.szExeFile,len)==0)
blExist=TRUE;
其中語句if(_strnicmp(sPath,pe.szExeFile,len)==0)就是判斷該進(jìn)程的可執(zhí)行文件的路徑是否在安裝程序所在的臨時(shí)路徑下,若是則將blExist置為TRUE。參數(shù)pe是一個(gè)PROCESSENTRY32類型的結(jié)構(gòu),pe.th32ProcessID包含了獲取的進(jìn)程標(biāo)識(shí)符,pe.szExeFile為該進(jìn)程的可執(zhí)行文件路徑和名稱。
2.3 循環(huán)調(diào)用系統(tǒng)函數(shù)Process32Next()。循環(huán)調(diào)用系統(tǒng)函數(shù)Process32Next()獲取其余進(jìn)程的信息:
while(blExist==FALSE ::Process32Next(hSnapshot,pe))
{
if(_strnicmp(sPath,pe.szExeFile,len)==0)
{
blExist=TRUE; break;
}
}
作用與第2步中的基本相同。
2.4 設(shè)置事件。經(jīng)過上述判斷,如果安裝過程已經(jīng)結(jié)束,則將事件hEvent置為有信號(hào)狀態(tài):
::CloseHandle(hSnapshot);
L1:if(blExist==FALSE) ::SetEvent(hEvent);
3 結(jié)束語
本文簡要介紹了自動(dòng)安裝程序?qū)崿F(xiàn)原理和方法,其主要目的是想與有興趣的朋友一起切磋一下實(shí)現(xiàn)思路,希望能對軟件編程愛好的朋友有所幫助。所有實(shí)現(xiàn)代碼均已在VC++6.0和Windows XP下調(diào)試通過。
參考文獻(xiàn):
[1]理查特.王建華等譯.Windows核心編程[M].北京:機(jī)械工業(yè)出版社,2006.
[2]唐麗麗.WINDOWS系統(tǒng)中代碼的動(dòng)態(tài)嵌入執(zhí)行技術(shù)[J].武漢理工大學(xué)學(xué)報(bào)(交通科學(xué)與工程版),2002(01):51-55.
[3]本書編寫組.新編Windows API參考大全[M].北京:電子工業(yè)出版社,2000.
[4]王強(qiáng),周明,李定國.Windows API for 2000/XP實(shí)例精解[M].北京:電子工業(yè)出版社,2002.
作者簡介:段英杰(1983-),女,江蘇常州人,講師,主要從事計(jì)算機(jī)軟件研究。
作者單位:常州劉國鈞高等職業(yè)技術(shù)學(xué)校,江蘇常州 213025