工作中經常碰到一些程序,它們在系統啟動的過程中,自動打開並運行,以便實現對系統的監控或者病毒的檢測等特定的目的,典型的例子就是常用的一些殺毒軟件如:KV300及瑞星殺毒軟件等。筆者在此,以自己的編程實踐為基礎,說明這些程序自動啟動的原理和方法,同時對一些典型程序代碼進行分析,以便讀者在今後的編程過程中使用。
一、 程序自動啟動的原理及方法: 1. 利用WIN.INI文件實現相關程序的自動啟動 WIN.INI是系統保存在C:WINDOWS目錄下的一個系統初始化文件。系統在起動時會檢索該文件中的相關項,以便對系統環境的初始設置。
在該文件中的"[windows]"數據段中,有兩個數據項"load="和"run=",它們的作用就是在系統起動之後自動得裝入和運行相關的程序。假如我們需要在系統起動之後裝入並運行一個程序,只將需要運行文件的全文件名添加在該數據項的後面系統起動後就會自動運行該程序,系統也會進入特定的操作環境中去。
2. 利用注冊表實現相關程序的自動啟動
系統注冊表保存著系統的軟件、硬件及其他與系統配置有關的重要信息,一個計算機系統的系統注冊表一旦遭到破壞,整個系統將無法運行。
在計算機的系統注冊表中的子目錄中有一個目錄的名稱為HKEY_LOCAL_MACHINESoftware MicrosoftWindowsCurrent_VersionRun,假如你想讓程序在系統起動的過程中啟動該程序,就可以向該目錄添加一個子項,具體的過程是在注冊表中右擊該項,選中其中的"新建"項目,然後選中其中的"串值",建立新的串值後將它的名稱改成相應的名稱,雙擊新建的串值,輸入新的數值,自動啟動程序的過程就設置完成。
二、 利用VC++編程實現程序自動啟動的編程實例。 微軟公司提供的VC++ 6.0程序開發工具功能非常強大。在VC++ 6.0中同時具有對注冊表和*.INI文件操作的函數。筆者經過一段時間的摸索,成功的利用VC++ 6.0開發成功了一個小軟件,該軟件利用系統自動啟動程序的原理,將原來需要的繁瑣的手動工作轉變成成計算機的自動設置工作,使系統自動啟動相關程序的設置工作變的非常簡單可靠。
1.程序功能概述: 程序的主界面是對話框,在主界面對話框中有編輯框(EDIT BOX),圓形按鈕(RADIO BUTTON)和普通按鈕(COMMON BUTTON)組成。操作者通過向編輯框中添加需要自動加載的程序的全文件名(也可以通過浏覽按鈕來完成),然後通過對兩個RADIO BUTTON的選擇,進而完成對加載方式的選擇(是選用注冊表方式還是選者修改WIN.INI文件的方式),最後操作者通過點擊"應用"按鈕實現程序的自動加載功能,同時系統會提示操作者是否將操作計算機重新啟動,以便觀察程序的具體功能完成情況。程序在WIN98中調試運行正常。
2.編碼說明: ① 浏覽按鈕的功能代碼:
void CAutoloadDlg::OnLiulan()
{
// TODO: Add your control notification handler code here
CFileDialog fileDlg(TRUE,_T("EXE"),_T("*.exe"),OFN_HIDEREADONLYOFN_OVERWRITEPROMPT,(_T("Executable Files (*.exe) *.exe ")));//顯示打開文件的對話框
if(fileDlg.DoModal()==IDOK)//當操作者選擇OK時,程序,取得選擇文//件的全路徑名(包括文件的路徑及文件名稱),並將相應的數值傳輸給相//關的控件變量。
{
m_filename=fileDlg.GetPathName();//m_filename是EDIT BOX控件的相應的變量。
UpdateData(FALSE);//向將變量中的數值傳輸給控件顯示出來。
}
}
② 應用按鈕的功能代碼:
void CAutoloadDlg::OnOK()
{
// TODO: Add extra validation here
LPCTSTR title;
UpdateData(TRUE);
if(m_title.IsEmpty())//假如操作者沒有填寫要設置項的標題,程序顯示對話框,提示操作者進行相關的填寫。
{
MessageBox(_T("Please input the title name"));
return;
}
title=m_title;
if(m_filename.IsEmpty())//假如操作者沒有選擇要設置的程序的全路徑文//件名,程序顯示對話框,提示操作者進行相關的選擇。
{
MessageBox(_T("Please input the programe file name"));
return;
}
if(IsDlgButtonChecked(IDC_RADIO1))//假如操作者選擇注冊表方式,程序修改系統的注冊表。
{
HKEY hKey;
LPCTSTR data_Set="SoftwareMicrosoftWindowsCurrentVersionRun";//設置注冊表中相關的路徑
Longret0=(::RegOpenKeyEx(HKEY_LOCAL_MACHINE,data_Set,0,KEY_WRITE,&hKey));//打開注冊表中的相應項
if(ret0!=ERROR_SUCCESS)
{
MessageBox("錯誤0");
}
int length=m_filename.GetLength()+1;//將控件中的內容進行轉換,以達到注冊表修改函數的參數調用需求。
for(int i=0;i {
if(m_filename[i]==92)
length=length+1;
}
DWord cbData=length;
LPBYTE lpb=new BYTE[length];
int j=0;
for(i=0;i {
if(m_filename[i]==92)
{
lpb[j]=92;
j++;
lpb[j]=92;
j++;
}
else
{
lpb[j]=m_filename[i];
j++;
}
}
lpb[j]=0;
long ret1=(::RegSetValueEx(hKey,title,NULL,REG_SZ,lpb,cbData));//將相關的信息寫入注冊表。
if(ret1!=ERROR_SUCCESS)//判定系統的相關注冊是否成功?
{
MessageBox("錯誤1");
}
delete lpb;
::RegCloseKey(hKey);//關閉注冊表中的相應的項
}
if(IsDlgButtonChecked(IDC_RADIO2))//假如操作者選擇用修改WIN.INI文件的方式
{
LPCTSTR filename;
filename=m_filename;
WritePrivateProfileString(_T("windows"),_T("load"),filename,_T("c:windowswin.ini"));
WritePrivateProfileString(_T("windows"),_T("run"),filename,_T("c:windowswin.ini"));
}
yzdlg.DoModal();//顯示對話框,提示操作者是否需要重新啟動計算機,以便驗證程序的功能。
CDialog::OnOK();
}
③ 重新啟動按鈕的功能代碼:
void yanzheng::OnOK()
{
OSVERSIONINFO OsVerInfo;//保存系統版本信息的數據結構
OsVerInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&OsVerInfo);//取得系統的版本信息
if(OsVerInfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{
ExitWindowsEx(EWX_REBOOT,0);//重新啟動計算機
}
CDialog::OnOK();
}