国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

解析VC.NET擴展Windows磁盤清理工具的功能_.Net教程

2024-07-10 12:51:37
字體:
來源:轉載
供稿:網友

推薦:淺析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( 
/* [in] */ HKEY hkRegKey,
/* [in] */ LPCWSTR pcwszVolume,
/* [out] */ LPWSTR *ppwszDisplayName,
/* [out] */ LPWSTR *ppwszDescription,
/* [out] */ DWORD *pdwFlags) = 0;

virtual HRESULT STDMETHODCALLTYPE getspaceused(
/* [out] */ DWORDLONG *pdwlSpaceUsed,
/* [in] */ IEmptyVolumeCacheCallBack *picb) = 0;

virtual HRESULT STDMETHODCALLTYPE showproperties(
/* [in] */ HWND hwnd) = 0;

virtual HRESULT STDMETHODCALLTYPE purge(
/* [in] */ DWORDLONG dwlSpaceToFree,
/* [in] */ IEmptyVolumeCacheCallBack *picb) = 0;

virtual HRESULT STDMETHODCALLTYPE deactivate(
/* [out] */ DWORD *pdwFlags) = 0;

清理工具在正常執行時,首先調用Initialize初始化插件,隨后執行GetSpaceUsed來掃描可清除的文件大小。掃描完畢后,清理工具的主界面就出現了如圖1所示,在此,我們加入了清理TMP文件的功能可以瀏覽不同的清理文件種類。列表中的每一個文件種類均由一個COM插件實現。除了閱覽可清理文件大小以外,用戶在可以點擊一個可自定義的按鈕,調用插件的ShowProperties功能,以顯示更詳細的資料。如用戶選擇OK,清理工具就調用Purge函數,清理掃描出來的文件。最后,Deactivate函數被調用,終止插件的應用。

運用于Windows 2000以后的清理工具的插件也應該支持IEmptyVolumeCache的接口。IEmptyVolumeCache只由一個函數組成:

以下為引用的內容:

virtual /* [local] */ HRESULT STDMETHODCALLTYPE initializeex( 

/* [in] */ HKEY hkRegKey,
/* [in] */ LPCWSTR pcwszVolume,
/* [in] */ LPCWSTR pcwszKeyName,
/* [out] */ LPWSTR *ppwszDisplayName,
/* [out] */ LPWSTR *ppwszDescription,
/* [out] */ LPWSTR *ppwszBtnText,
/* [out] */ DWORD *pdwFlags) = 0;

InitializeEx增加了更嚴格的本地化語言要求,加強了國際化的支持,并且允許自定義按鈕的顯示文字。pdwFlags變量用于在工具與插件間傳遞信息,支持下列旗標:

以下為引用的內容:

EVCF_OUTOFDISKSPACE
EVCF_SETTINGSMODE
EVCF_DONTSHOWIFZERO
EVCF_ENABLEBYDEFAULT
EVCF_ENABLEBYDEFAULT_AUTO
EVCF_HASSETTINGS
EVCF_REMOVEFROMLIST

 

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 對象用于連接到數據源,該數據源是在連接字符串中

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武宁县| 资中县| 巴南区| 河间市| 怀来县| 大兴区| 儋州市| 西藏| 雅江县| 岳普湖县| 乌苏市| 佛学| 商丘市| 郸城县| 大邑县| 乌兰浩特市| 高要市| 阜新市| 正定县| 琼结县| 丽水市| 彝良县| 阜城县| 乌兰浩特市| 延寿县| 清流县| 仙游县| 都匀市| 通江县| 盐山县| 合阳县| 松桃| 吉木萨尔县| 盐津县| 正蓝旗| 深圳市| 象山县| 北碚区| 孟津县| 南充市| 德庆县|