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

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:淺析vc.net中配置OpenOffice的SDK應(yīng)用開發(fā)
      在vc.net 2003下利用OpenOffice的SDK開發(fā)應(yīng)用程序,其實很簡單,看下面的配置方法。 需求軟件: MS Visual C Net 2003 OpenOffice SDK OpenOffice.org 2.1.x 或者更高版本 軟件下

      摘 要 介紹了Windows磁盤清理工具二次開發(fā)的擴展接口,對其COM接口加以分解,并運用ATL庫具體實現(xiàn)了清理“*.tmp”臨時文件的功能。

      關(guān)鍵詞 磁盤清理工具、ATL庫、COM接口。

      引言

      Windows磁盤清理工具(Disk CleanUp)是一個實用快捷并擁有簡單易用界面的系統(tǒng)清理軟件,更值得系統(tǒng)開發(fā)管理人員注意的是,此系統(tǒng)清理軟件是建立在以COM技術(shù)為基礎(chǔ)發(fā)展的,支持第三方插件,并且可以根據(jù)需要自制定義功能二次開發(fā)的平臺。在這里,我們對于Windows磁盤清理工具的開發(fā)接口做深入地研究,在此基礎(chǔ)上舉例示范添加一個查找“*.tmp”臨時文件的功能。

      技術(shù)討論

      微軟的COM技術(shù)廣泛地運用在Windows的模塊化設(shè)計中,致使支持二次開發(fā)。關(guān)于COM技術(shù)基礎(chǔ)與應(yīng)用,可參考。在此,我們只為Windows磁盤清理工具,簡稱清理工具的擴展接口加以分解。清理工具首次出現(xiàn)在Windows 98操作系統(tǒng)中,并在后來推出的Windows版本中予以改進,添加了新的功能。比如說,在NTFS的文件系統(tǒng)下,自動壓縮不經(jīng)常訪問的文件。這些新功能通過COM模塊實現(xiàn),在清理工具中作為插件調(diào)用。早期的版本是通過IEmptyVolumeCache接口調(diào)用,在Windows 2000以后的版本中,還加入了IEmptyVolumeCache2接口,加入了較小的更新。

      IEmptyVolumeCache接口由五個函數(shù)組成,根據(jù)呼叫的順序,分別是:

      以下為引用的內(nèi)容:

      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;

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

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

      以下為引用的內(nèi)容:

      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變量用于在工具與插件間傳遞信息,支持下列旗標:

      以下為引用的內(nèi)容:

      EVCF_OUTOFDISKSPACE
      EVCF_SETTINGSMODE
      EVCF_DONTSHOWIFZERO
      EVCF_ENABLEBYDEFAULT
      EVCF_ENABLEBYDEFAULT_AUTO
      EVCF_HASSETTINGS
      EVCF_REMOVEFROMLIST

       

      EVCF_OUTOFDISKSPACE與EVCF_SETTINGSMODE用于工具傳遞給插件的設(shè)定。EVCF_OUTOFDISKSPACE表示當前硬盤的空余空間非常有限,需要盡可能多地清理,即使是系統(tǒng)的性能會受到影響。EVCF_SETTINGSMODE表示可定期執(zhí)行的無人控制模式。在此模式下,GetSpaceUsed,Purge,及ShowProperties都將不予調(diào)用,所有清理任務(wù)應(yīng)予InitializeEx時執(zhí)行。其它旗標用于插件傳遞給工具的不同運行模式。EVCF_DONTSHOWIFZERO表示在沒有找到可刪除文件時不顯示此類型,EVCF_ENABLEBYDEFAULT表示此類型文件可以安全刪除,EVCF_ENABLEBYDEFAULT_AUTO表示此類型文件可以非常安全的刪除,EVCF_HASSETTINGS表示此插件支持ShowProperties功能,可以顯示詳細信息。EVCF_REMOVEFROMLIST表示是一次性清理任務(wù),清理工具在執(zhí)行后自動將插件關(guān)閉,以后不再執(zhí)行。

      實現(xiàn)方法

        我們開發(fā)一個新的清理工具插件,掃描并清理*.TMP文件。COM的編程有多種方法,我們選擇了ATL庫。關(guān)于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;

        然后,我們一一實現(xiàn)IEmptyVolumeCache及IEmptyVolumeCache2接口的函數(shù)。在下面的代碼列表中,沒有包括嚴格的檢查錯誤返回值。這是為了簡短代碼的長度,提高可讀性。在實際應(yīng)用中,檢查錯誤返回值是不可少的。為了不同版本W(wǎng)indows兼容,我們在InitializeEx中調(diào)用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中,我們調(diào)用ScanDir來掃描*.TMP文件,儲存在m_lstFilesToDel中。GetSpaceUsed的第二個參數(shù)是IEmptyVolumeCacheCallBack接口的指針,用于調(diào)用其ScanProgress函數(shù)以報告掃描的進展情況。ScanProgress函數(shù)定義是:

      HRESULT ScanProgress(DWORDLONG dwlSpaceUsed, DWORD dwFlags, LPCWSTR pwszReserved);

        其中dwFlags正常應(yīng)設(shè)為零,在結(jié)束時改為EVCCBF_LASTNOTIFICATION。ScanProgress函數(shù)的返回值很重要,因為用戶可以在任何時候中斷在進行中的清理任務(wù)。如ScanProgress返回E_ABORT,GetSpaceUsed應(yīng)最快終端掃描,函數(shù)返回。因此,我們在遞歸的目錄掃描函數(shù)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;
      }

        其他的函數(shù)很簡單。Purge函數(shù)將掃描出的文件列表m_lstFilesToDel中的文件一一刪除。ShowProperties中,我們顯示掃描出來的文件。最后,Deactivate將分配的內(nèi)存釋放。

      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;

        結(jié)論和建議

        通過實例分解,我們對Windows磁盤清理工具的基于COM技術(shù)的開發(fā)接口做了深入地研究。Windows外殼中有較多的開發(fā)接口,本文介紹的開發(fā)思想也可以運用在其它擴展插件中。

      分享:.net編程之如何綁定到ADO.NET數(shù)據(jù)源
      本示例演示如何將 Windows Presentation Foundation (WPF) ListBox 控件綁定到 ADO.NET DataSet。 示例 在本示例中,OleDbConnection 對象用于連接到數(shù)據(jù)源,該數(shù)據(jù)源是在連接字符串中

      來源:模板無憂//所屬分類:.Net教程/更新時間:2009-09-18
      相關(guān).Net教程