推薦:淺析vc.net中配置OpenOffice的SDK應用開發在vc.net 2003下利用OpenOffice的SDK開發應用程序,其實很簡單,看下面的配置方法。需求軟件:MS Visual C Net 2003OpenOffice SDKOpenOffice.org 2.1.x 或者更高版本軟件下
摘 要 介紹了Windows磁盤清理工具二次開發的擴展接口,對其COM接口加以分解,并運用ATL庫具體實現了清理“*.tmp”臨時文件的功能。
關鍵詞 磁盤清理工具、ATL庫、COM接口。
引言
Windows磁盤清理工具(Disk CleanUp)是一個實用快捷并擁有簡單易用界面的系統清理軟件,更值得系統開發管理人員注意的是,此系統清理軟件是建立在以COM技術為基礎發展的,支持第三方插件,并且可以根據需要自制定義功能二次開發的平臺。在這里,我們對于Windows磁盤清理工具的開發接口做深入地研究,在此基礎上舉例示范添加一個查找“*.tmp”臨時文件的功能。
技術討論
微軟的COM技術廣泛地運用在Windows的模塊化設計中,致使支持二次開發。關于COM技術基礎與應用,可參考。在此,我們只為Windows磁盤清理工具,簡稱清理工具的擴展接口加以分解。清理工具首次出現在Windows 98操作系統中,并在后來推出的Windows版本中予以改進,添加了新的功能。比如說,在NTFS的文件系統下,自動壓縮不經常訪問的文件。這些新功能通過COM模塊實現,在清理工具中作為插件調用。早期的版本是通過IEmptyVolumeCache接口調用,在Windows 2000以后的版本中,還加入了IEmptyVolumeCache2接口,加入了較小的更新。
IEmptyVolumeCache接口由五個函數組成,根據呼叫的順序,分別是:
| 以下為引用的內容: virtual /* [local] */ HRESULT STDMETHODCALLTYPE initialize( |
運用于Windows 2000以后的清理工具的插件也應該支持IEmptyVolumeCache的接口。IEmptyVolumeCache只由一個函數組成:
| 以下為引用的內容: virtual /* [local] */ HRESULT STDMETHODCALLTYPE initializeex( |
InitializeEx增加了更嚴格的本地化語言要求,加強了國際化的支持,并且允許自定義按鈕的顯示文字。pdwFlags變量用于在工具與插件間傳遞信息,支持下列旗標:
| 以下為引用的內容: EVCF_OUTOFDISKSPACE |
EVCF_OUTOFDISKSPACE與EVCF_SETTINGSMODE用于工具傳遞給插件的設定。EVCF_OUTOFDISKSPACE表示當前硬盤的空余空間非常有限,需要盡可能多地清理,即使是系統的性能會受到影響。EVCF_SETTINGSMODE表示可定期執行的無人控制模式。在此模式下,GetSpaceUsed,Purge,及ShowProperties都將不予調用,所有清理任務應予InitializeEx時執行。其它旗標用于插件傳遞給工具的不同運行模式。EVCF_DONTSHOWIFZERO表示在沒有找到可刪除文件時不顯示此類型,EVCF_ENABLEBYDEFAULT表示此類型文件可以安全刪除,EVCF_ENABLEBYDEFAULT_AUTO表示此類型文件可以非常安全的刪除,EVCF_HASSETTINGS表示此插件支持ShowProperties功能,可以顯示詳細信息。EVCF_REMOVEFROMLIST表示是一次性清理任務,清理工具在執行后自動將插件關閉,以后不再執行。
實現方法
我們開發一個新的清理工具插件,掃描并清理*.TMP文件。COM的編程有多種方法,我們選擇了ATL庫。關于ATL庫的運用。
我們在Visual Studio .Net 2003中生成新的ATL的DLL Server項目,并使用Add Class加入新的ATL Simple Object控件類CCleanSimpleHandler。在定義中,我們讓CCleanSimpleHandler從IEmptyVolumeCache2繼承。并且,我們添加了下列變量:
// 儲存掃描出文件的大小
DWORDLONG m_dwlFileSize;
// 儲存根目錄
WCHAR m_strRootDir[MAX_PATH];
// 儲存掃描出文件列表
std::vector<WCHAR *> m_lstFilesToDel;
然后,我們一一實現IEmptyVolumeCache及IEmptyVolumeCache2接口的函數。在下面的代碼列表中,沒有包括嚴格的檢查錯誤返回值。這是為了簡短代碼的長度,提高可讀性。在實際應用中,檢查錯誤返回值是不可少的。為了不同版本Windows兼容,我們在InitializeEx中調用Initialize。
HRESULT CCleanSimpleHandler::InitializeEx (HKEY hKey, LPCWSTR pcwszVolume, LPCWSTR pcwszKeyName, LPWSTR *ppwszDisplayName, LPWSTR *ppwszDescription, LPWSTR *ppwszBtnText, DWORD *pdwFlags)
{
HRESULT hr = Initialize (hKey, pcwszVolume, ppwszDisplayName, ppwszDescription, pdwFlags);
*ppwszBtnText = (LPWSTR) CoTaskMemAlloc (64 * sizeof (WCHAR));
StrCpyW(*ppwszBtnText, L"View files");
return hr;
}
HRESULT CCleanSimpleHandler::Initialize (HKEY hKey, LPCWSTR pcwszVolume, LPWSTR *ppwszDisplayName, LPWSTR *ppwszDescription, DWORD *pdwFlags)
{
StrCpyW(m_strRootDir, pcwszVolume);
*ppwszDisplayName = (LPWSTR) CoTaskMemAlloc(256 * sizeof (WCHAR));
StrCpyW(*ppwszDisplayName, L"*.TMP files");
*ppwszDescription = (LPWSTR) CoTaskMemAlloc (256 * sizeof (WCHAR));
StrCpyW(*ppwszDescription, L"Temporary files - *.TMP");
*pdwFlags = EVCF_HASSETTINGS | EVCF_ENABLEBYDEFAULT;
m_dwlFileSize = 0;
return S_OK;
}
在GetSpaceUsed中,我們調用ScanDir來掃描*.TMP文件,儲存在m_lstFilesToDel中。GetSpaceUsed的第二個參數是IEmptyVolumeCacheCallBack接口的指針,用于調用其ScanProgress函數以報告掃描的進展情況。ScanProgress函數定義是:
HRESULT ScanProgress(DWORDLONG dwlSpaceUsed, DWORD dwFlags, LPCWSTR pwszReserved);
其中dwFlags正常應設為零,在結束時改為EVCCBF_LASTNOTIFICATION。ScanProgress函數的返回值很重要,因為用戶可以在任何時候中斷在進行中的清理任務。如ScanProgress返回E_ABORT,GetSpaceUsed應最快終端掃描,函數返回。因此,我們在遞歸的目錄掃描函數ScanDir中,加入了如中斷立即退出的功能。
HRESULT CCleanSimpleHandler::GetSpaceUsed (DWORDLONG *pdwSpaceUsed, IEmptyVolumeCacheCallBack *picb)
{
m_dwlFileSize = 0;
ScanDir(m_strRootDir, picb);
picb->ScanProgress(m_dwlFileSize, EVCCBF_LASTNOTIFICATION ,NULL);
*pdwSpaceUsed = m_dwlFileSize;
return S_OK;
}
bool CCleanSimpleHandler::ScanDir(WCHAR * szDir, IEmptyVolumeCacheCallBack *pcib)
{
WCHAR strPath[MAX_PATH];
WCHAR* pchPathFileName;
bool cancelled = false;
WIN32_FIND_DATAW fd;
HANDLE hFind;
if (cancelled = FAILED(pcib->ScanProgress(m_dwlFileSize, NULL, NULL))) return false;
StrCpyW(strPath,szDir);
PathAppendW(strPath, L"*");
pchPathFileName = strPath+lstrlenW(strPath)-1;
hFind = FindFirstFileW(strPath, &fd);
if (hFind == INVALID_HANDLE_VALUE) // E.g. Due to security issues
return true;
do {
StrCpyW(pchPathFileName, fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (fd.cFileName[0] != '.') {
if (cancelled = !ScanDir(strPath, pcib)) break;
}
} else {
WCHAR* pchExt = PathFindExtensionW(strPath);
if ( StrCmpIW(pchExt, L".tmp") == 0 ) {
m_dwlFileSize += ((DWORDLONG)fd.nFileSizeHigh)*4294967295+fd.nFileSizeLow;
WCHAR* filename = (WCHAR *)CoTaskMemAlloc((lstrlenW(strPath)+1)*sizeof(WCHAR));
StrCpyW(filename, strPath);
m_lstFilesToDel.push_back(filename);
}
}
} while (FindNextFileW(hFind, &fd) != NULL);
FindClose(hFind);
return !cancelled;
}
其他的函數很簡單。Purge函數將掃描出的文件列表m_lstFilesToDel中的文件一一刪除。ShowProperties中,我們顯示掃描出來的文件。最后,Deactivate將分配的內存釋放。
HRESULT CCleanSimpleHandler::Purge (DWORDLONG dwSpaceToFree, IEmptyVolumeCacheCallBack *picb)
{
for (unsigned int i=0; i < m_lstFilesToDel.size(); ++i)
DeleteFileW(m_lstFilesToDel[i]);
return S_OK;
}
HRESULT CCleanSimpleHandler::ShowProperties (HWND hWnd)
{
for (unsigned int i=0; i < m_lstFilesToDel.size(); ++i)
if (MessageBoxW(hWnd, m_lstFilesToDel[i], L"View files",
MB_OKCANCEL|MB_ICONINFORMATION)==IDCANCEL) break;
return S_OK;
}
HRESULT CCleanSimpleHandler::Deactivate (LPDWORD pdwFlags)
{
for (unsigned int i=0; i < m_lstFilesToDel.size(); ++i)
CoTaskMemFree(m_lstFilesToDel[i]);
m_lstFilesToDel.clear();
*pdwFlags = 0;
return S_OK;
結論和建議
通過實例分解,我們對Windows磁盤清理工具的基于COM技術的開發接口做了深入地研究。Windows外殼中有較多的開發接口,本文介紹的開發思想也可以運用在其它擴展插件中。
分享:.net編程之如何綁定到ADO.NET數據源本示例演示如何將 Windows Presentation Foundation (WPF) ListBox 控件綁定到 ADO.NET DataSet。示例 在本示例中,OleDbConnection 對象用于連接到數據源,該數據源是在連接字符串中
新聞熱點
疑難解答
圖片精選