文件的非递归深层搜索VISTA(程序代码)

来源:互联网 发布:加载更多js 编辑:程序博客网 时间:2024/06/03 20:07

前一阵看了一篇关于文件夹递归搜索的文章于是就自己动手学写了一个,在VISTA下一运行才发现出现了好多问题。最后不得不彻底改变代码,把代码写出来分享一下虽然没什么大用处。总结就是VISTA 确实比XP要安全多了,权限和目录的分配也比XP要智能。

 

主要是核心代码,安全性和稳定性都没考虑,水平不行仅供参考

思想是,自己定义一个结构用来保存每次文件夹变化时的HFILE句柄,当程序一个文件夹全部搜索完成后就返回上一层继续上一次保存的HFILE句柄进行搜索,当结构中的句柄全部被用到后就退出搜索。

struct LhFile
{
 HANDLE hfilelements[MAX_PATH];//用来保存hFile,可以定义搜索的深度,我定义是MAX_PATH层
 int last;
};

 

void Search(char* szFilename)
{
struct LhFile* L;
int D,T,P;
BOOL bRet;
char filename[MAX_PATH];
HANDLE hFile;
WIN32_FIND_DATA fd;
bRet = TRUE;
L=(struct LhFile*)malloc(sizeof(struct LhFile));
L->hfilelements[0]=0;
L->last=0;
hFile = FindFirstFile("*", &fd);
D=1;//struct LhFile中的hfilelement为空(就是全部搜索完成)
 while(D)
 {
  do{
   T=1;
   if(L->last>=MAX_PATH-1) T=0;//*如果连满退出循环
   else
   {
     do{
        if(L->last>=MAX_PATH-1) P=0;//*如果连满退出循环
        else
  {
           P=0;//如果不是文件夹退出循环
           if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))// 如果是目录
     {
             lpszLinkName=fd.cFileName;
             if(fd.cFileName[0]!='.' && !myIFLINKFILE(lpszLinkName))//如果目录名的首字符为.文件夹则不用进行查找
    {
        if(SetCurrentDirectory(fd.cFileName))//如果文件夹打不开跳过(系统权限或其它原因)
     {
               myINSERT(L,hFile);
               //GetCurrentDirectory(MAX_PATH,filename);//调试时使用
               hFile = FindFirstFile("*", &fd);
     }
     else bRet = FindNextFile(hFile, &fd);
    }
    else
    {
              bRet = FindNextFile(hFile, &fd);
    }
     if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) P=1;
     }
  }
  }while(hFile != INVALID_HANDLE_VALUE && bRet && P);
      if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))//如果不是文件夹(因链满退出循环的情况)
   {
        if(!stricmp(fd.cFileName, szFilename)) // stricmp对两字符串进行小写形式的对比, 返回为0表示完全一致
     {
           GetCurrentDirectory(MAX_PATH,filename); // 先获得当前工作目录的全路径
              MessageBox(_hWnd,filename,"搜索结果",0); //输出显示
     }
  bRet = FindNextFile(hFile, &fd);
   }
   }
  }while(hFile != INVALID_HANDLE_VALUE && bRet && T);  
SetCurrentDirectory(".."); //搜索一个文件夹没有文件返回上一层
//GetCurrentDirectory(MAX_PATH,filename);//调试时使用
  if(L->hfilelements[0]!=0)
  {
 do{
   hFile=L->hfilelements[L->last];
      bRet = FindNextFile(hFile, &fd);
   if(!bRet)
   {
       SetCurrentDirectory("..");//搜索一个文件夹没有文件返回上一层(主要是空文件夹)
    //GetCurrentDirectory(MAX_PATH,filename);//调试时使用
    myDELETE(L);
   }
   if(L->hfilelements[0]==0) D=0;
 }while(!bRet && D);
    if(L->hfilelements[0]==0) D=0;
 else myDELETE(L);
  }
  else
  {
    D=0;
  }
 }
MessageBox(_hWnd,"搜索结束","搜索结果",0);
}

void myINSERT(struct LhFile* L,HANDLE hFile)
{
 if(L->last>=MAX_PATH-1)//*
  MessageBox(_hWnd,"错误,文件链满","错误提示",0);
 else
 {
  if(L->hfilelements[0]==0)
   L->hfilelements[L->last]=hFile;
  else
  {
   L->last=L->last+1;
      L->hfilelements[L->last]=hFile;
  }
 }
}

void myDELETE(struct LhFile *L)
{
 if(L->hfilelements[0]==0)
  MessageBox(_hWnd,"错误,文件链空","错误提示",0);
 else
 {
  L->hfilelements[L->last]=0;
  if(L->last!=0)
   L->last=L->last-1;
 }
}

BOOL myIFLINKFILE(LPCTSTR lpszLinkName) //判断是否是.lnk文件夹(好像没必要)
{
HRESULT hres;
IShellLink *pShLink;
hres = CoInitialize(NULL);
//hres = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void **)&pShLink);
hres = CoCreateInstance( &CLSID_ShellLink,
                               NULL,
                               CLSCTX_INPROC_SERVER,
                               &IID_IShellLink,
                               (LPVOID *)&pShLink );
if (SUCCEEDED(hres))
{
 IPersistFile *ppf;
 hres = pShLink->lpVtbl->QueryInterface(pShLink,
                                            &IID_IPersistFile,
                                            (LPVOID *)&ppf );
 //hres = pShLink->QueryInterface(IID_IPersistFile,(void **)&ppf);
 if (SUCCEEDED(hres))
 {
  WORD wsz[MAX_PATH];
  MultiByteToWideChar( CP_ACP, 0,
                                 lpszLinkName,
                                 -1, wsz, MAX_PATH );
  //MultiByteToWideChar(CP_ACP,0,lpszLinkName,-1, wsz, MAX_PATH );
  hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ );
  //hres = ppf->Load(wsz, STGM_READ);
  ppf->lpVtbl->Release(ppf);
 }
ppf->lpVtbl->Release((IPersistFile *)pShLink);
}
return SUCCEEDED(hres);
}