这几天都在调试一个问题就是用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);
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;
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;
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这个函数很不好用,刚开始我也这么认为,但是当我真正找到原因之后,才知道是自己学艺不精,呵呵
这里特给自己做一个记号,也给在网上很多人,在这个问题上没有找到答案的朋友一个提示,看看是不是和我一样的错误,最终能够解决问题
也请大神们多多指教