选择显示字体大小

vc.net扩展windows磁盘清理工具的功能

摘 要 介绍了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表示是一次性清理任务,清理工具在执行后自动将插件关闭,以后不再执行。



图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_okcancelmb_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外壳中有较多的开发接口,本文介绍的开发思想也可以运用在其它扩展插件中。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons