繁体   English   中英

Delphi中的文件搜索忽略了一些Windows目录

[英]File search in Delphi is ignoring some Windows directories

我正在此线程( 如何通过Delphi中的所有子目录搜索文件)中使用以下代码来递归查找文件:

procedure FindFilePattern(root:String;pattern:String);
var
  SR:TSearchRec;
begin
  root:=IncludeTrailingPathDelimiter(root);
  if FindFirst(root+'*.*',faAnyFile,SR) = 0 then
  begin
      repeat
          Application.ProcessMessages;
          if ((SR.Attr and faDirectory) = SR.Attr ) and (pos('.',SR.Name)=0) then
             FindFilePattern(root+SR.Name,pattern)
          else
          begin
           if pos(pattern,SR.Name)>0 then Form1.ListBox1.Items.Add(Root+SR.Name);
          end;
      until FindNext(SR)<>0;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FindFilePattern('C:\','.exe');
end;

它正在工作,但是由于某种原因,它忽略了目录Program Files,Program Files(x86)和Users。 不幸的是,我正在搜索的文件位于这些文件夹中。 有人知道为什么会这样吗?

任何提示都会非常有帮助,

谢谢

就像杰里·道奇(Jerry Dodge)提到的那样,担保权无疑是您可能需要考虑的一件事。 您的代码可能需要以管理员身份运行才能访问各种系统目录以及属于其他用户的目录。 在大多数情况下,仅枚举您提到的目录不需要提升的权限。 但是,如果您发现遇到的目录,可以执行以下任一操作:

  1. 将UAC清单添加到要求提升的应用程序中

  2. 将枚举代码移到单独的进程或COM对象中,然后可以在需要时从未提升的进程运行提升的代码。

但是除此之外,您复制的FindFilePattern()过程一开始也是错误地实现的。 它是:

  1. 错误地比较文件属性。 如果条目是文件或目录上没有属性 ,则表达式(SR.Attr and faDirectory) = SR.Attr )将为true。 遇到具有属性的目录(例如系统目录,压缩目录,索引目录等)并不少见。

  2. 错误地比较文件名。 对于不包含的所有文件和目录,表达式(pos('.',SR.Name)=0)将为true . 完全没有个性。 几乎所有文件都有一个. ,甚至目录也可以有一个. 也一样 处理目录时,您需要忽略special即可. ..目录条目,而不是任何带有. 在里面。

  3. 更糟糕的是,#1和#2的共同作用是允许具有属性的目录和包含的目录. ,被视为文件而不是目录。 该代码通常无法正确处理目录,更不用说递归了。

  4. 泄漏所有搜索句柄。 无论FindNext()如何,如果FindFirst()成功,则必须调用FindClose() FindNext()

尝试类似这样的方法:

uses
  SysUtils, Masks;

procedure FindFilePattern(root: String; pattern: String);
var
  SR: TSearchRec;
begin
  root := IncludeTrailingPathDelimiter(root);
  if FindFirst(root + '*.*', faAnyFile, SR) = 0 then
  try
    repeat
      Application.ProcessMessages;
      if (SR.Attr and faDirectory) <> 0 then
      begin
        if (SR.Name <> '.') and (Sr.Name <> '..') then
          FindFilePattern(root + SR.Name, pattern);
      end else
      begin
        if MatchesMask(SR.Name, pattern) then
          Form1.ListBox1.Items.Add(Root + SR.Name);
      end;
    until FindNext(SR) <> 0;
  finally
    FindClose(SR);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FindFilePattern('C:\', '*.exe');
end;

您的应用程序需要以提升的特权运行,才能访问您所说的子目录中的某些子目录。 作为临时测试,运行“以管理员身份”进行验证。 如果确实如此,则应添加清单以在启动时要求提升。

Delphi的更高版本具有此内置功能。 在“项目选项”下,转到“应用程序”页面,然后选中“启用管理员权限”。 当然,这是使用IDE的快速简便的方法,您应该考虑编写自己的自定义清单,尤其是在运行没有此选项的较旧版本的Delphi时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM