让我头疼的SHFileOperation函数删除文件夹,呵呵

时间:2022-03-25 21:37:42

这几天都在调试一个问题就是用SHFileOperation函数删除文件夹总是出现如下问题

让我头疼的SHFileOperation函数删除文件夹,呵呵 

呵呵,很头疼,那个程序在使用呢?肯定是我自己的程序了。自己找了找程序,觉得没问题,就去看删除文件夹的函数,代码如下:

  1   function  DeleteDirectory(DeleteStr: String): Boolean;
 
2   var
 
3    f: TSHFILEOPSTRUCT;
 
4   begin
 
5    FillChar(f, SizeOf(TSHFILEOPSTRUCT,  0 );
 
6     with  f  do
 
7     begin
 
8      fFlags : =  FOF_NOCONFIRMATION;  // 这里的属性很多,我就不说了,有需要的自己查查看
 
9      Wnd : =   0 ;
10      wFunc : =  FO_DELETE;  // 这里当然是使用删除的属性了
11      pFrom : =  PChar(DeleteStr  +  # 0 );  // 这里网上很多人提到要在最后加一个# 0 ,否则会报其他错误
12      pTo : =   nil ;
13     end ;
14    Result : =  (SHFileOperation(f)  =   0);

15 end 

来回测试很多次,换了很多属性,还是这个错误 ,回头想了一下,被一个程序占用,肯定是我自己的程序了

所以又检查扫描文件夹目录的过程,代码如下:

 1  procedure  TForm1.SCanTreeView;
 2  var
 3    DirectoryStr: String;
 4    DirSr, FileSr: TSearchRec;
 5    FileStrList, StrList: TStringList;
 6    I: Integer;
 7    DirNode, FileNode: TTreeNode;
 8  begin
 9     for  I : =  RzTreeView1.Items.Count  -   1   downto   0   do
10     begin
11       if  RzTreeView1.Items[i].Level  <>   0   then
12       begin
13        RzTreeView1.Items[i].Delete;
14       end ;
15     end ;
16    DirectoryStr : =  ExtractFilePath(ParamStr( 0 ));
17    StrList : =  TStringList.Create;
18    FileStrList : =  TStringList.Create;
19     if  FindFirst(DirectoryStr  +   ' * ' , faDirectory, DirSr)  =   0   then
20     begin
21      Repeat
22         if  ((DirSr.Attr  and  faDirectory)  =  faDirectory)  and  ((DirSr.Name  <>   ' . ' and  (DirSr.Name  <>   ' .. ' ))  then
23         begin
24          DirNode : =  RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
25          DirNode.ImageIndex : =   1 ;
26          DirNode.SelectedIndex : =   1 ;
27 
28           if  FindFirst(DirectoryStr  +  DirSr.Name  +   ' \*.cks ' , faAnyFile, FileSr)  =   0   then
29           begin
30            Repeat
31              FileStrList.Delimiter : =   ' \ ' ;
32              FileStrList.DelimitedText : =  FileSr.Name;
33              FileNode : =  RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count  -   1 ],  ' .cks ' '' , [rfReplaceAll]));
34              FileNode.ImageIndex : =   6 ;
35              FileNode.SelectedIndex : =   6 ;
36            Until FindNext(FileSr)  <>   0 ;
37           end ;
38         end ;
39      Until FindNext(DirSr)  <>   0 ;
40     end ;
41    FindClose(DirSr);
42    FindClose(FileSr);
43    StrList.Free;
44    FileStrList.Free;
45   RzTreeView1.FullExpand; 

46  end;

看完这个过程不知道大家有没有发现错误?呵呵,我也是测试了好久才发现这个错误

就是没有在FindNext(FileSr)<> 0 之后没有用CloseHandle(FileSr)关闭, 导致之前扫描的文件都被占用,所以每次删除都报错,这是一个很细微的错误,希望大家不要像我一样不仔细

正确的代码如下:

 2  procedure  TForm1.SCanTreeView;
 3  var
 4    DirectoryStr: String;
 5    DirSr, FileSr: TSearchRec;
 6    FileStrList, StrList: TStringList;
 7    I: Integer;
 8    DirNode, FileNode: TTreeNode;
 9  begin
10     for  I : =  RzTreeView1.Items.Count  -   1   downto   0   do
11     begin
12       if  RzTreeView1.Items[i].Level  <>   0   then
13       begin
14        RzTreeView1.Items[i].Delete;
15       end ;
16     end ;
17    DirectoryStr : =  ExtractFilePath(ParamStr( 0 ));
18    StrList : =  TStringList.Create;
19    FileStrList : =  TStringList.Create;
20     if  FindFirst(DirectoryStr  +   ' * ' , faDirectory, DirSr)  =   0   then
21     begin
22      Repeat
23         if  ((DirSr.Attr  and  faDirectory)  =  faDirectory)  and  ((DirSr.Name  <>   ' . ' and  (DirSr.Name  <>   ' .. ' ))  then
24         begin
25          DirNode : =  RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
26          DirNode.ImageIndex : =   1 ;
27          DirNode.SelectedIndex : =   1 ;
28 
29           if  FindFirst(DirectoryStr  +  DirSr.Name  +   ' \*.cks ' , faAnyFile, FileSr)  =   0   then
30           begin
31            Repeat
32              FileStrList.Delimiter : =   ' \ ' ;
33              FileStrList.DelimitedText : =  FileSr.Name;
34              FileNode : =  RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count  -   1 ],  ' .cks ' '' , [rfReplaceAll]));
35              FileNode.ImageIndex : =   6 ;
36              FileNode.SelectedIndex : =   6 ;
37            Until FindNext(FileSr)  <>   0 ;
38             CloseHandle(FileSr);  //注意这里,关闭掉FileSr;
39           end ;
40         end ;
41      Until FindNext(DirSr)  <>   0 ;
42     end ;
43    FindClose(DirSr);
44    FindClose(FileSr);
45    StrList.Free;
46    FileStrList.Free;
47   RzTreeView1.FullExpand;

48 end;  

在网上很多人说SHFileOperation这个函数很不好用,刚开始我也这么认为,但是当我真正找到原因之后,才知道是自己学艺不精,呵呵

这里特给自己做一个记号,也给在网上很多人,在这个问题上没有找到答案的朋友一个提示,看看是不是和我一样的错误,最终能够解决问题 

也请大神们多多指教