• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • VC.NET擴展Windows磁盤清理工具的功能

    發表于:2007-05-25來源:作者:點擊數: 標簽:windowsVC.NET清理磁盤擴展
    摘 要 介紹了 Windows 磁盤清理工具二次 開發 的擴展接口,對其COM接口加以分解,并運用ATL庫具體實現了清理*.tmp臨時文件的功能。 關鍵詞 磁盤清理工具、ATL庫、COM接口。 引言 Windows磁盤清理工具(Disk CleanUp)是一個實用快捷并擁有簡單易用界面的系統
     摘 要 介紹了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接口由五個函數組成,根據呼叫的順序,分別是:

    clearcase/" target="_blank" >cccccc" width="90%" align="center" bgcolor="#edeceb" border="1">
    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表示是一次性清理任務,清理工具在執行后自動將插件關閉,以后不再執行。



    圖1 清理工具的主界面

      實現方法

      我們開發一個新的清理工具插件,掃描并清理*.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外殼中有較多的開發接口,本文介紹的開發思想也可以運用在其它擴展插件中。

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>