Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中的文件搜索忽略了某些Windows目录_Windows_Delphi_Winapi - Fatal编程技术网

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

Delphi中的文件搜索忽略了某些Windows目录,windows,delphi,winapi,Windows,Delphi,Winapi,我使用此线程()中的以下代码递归查找文件: procedure FindFilePattern(root:String;pattern:String); var SR:TSearchRec; begin root:=IncludeTrailingPathDelimiter(root); if FindFirst(root+'*.*',faAnyFile,SR) = 0 then begin repeat Application.ProcessMes

我使用此线程()中的以下代码递归查找文件:

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;
过程FindFilePattern(根:字符串;模式:字符串);
变量
SR:TSearchRec;
开始
根:=包含RailingPathDelimiter(根);
如果FindFirst(根+'*.*',faAnyFile,SR)=0,则
开始
重复
Application.ProcessMessages;
如果((SR.Attr和faDirectory)=SR.Attr)和(pos('',SR.Name)=0),则
FindFilePattern(根+SR.Name,模式)
其他的
开始
如果pos(pattern,SR.Name)>0,则Form1.ListBox1.Items.Add(Root+SR.Name);
结束;
直到FindNext(SR)0;
结束;
结束;
程序TForm1.按钮1单击(发送方:TObject);
开始
FindFilePattern('C:\','.exe');
结束;
它正在工作,但出于某种原因,它忽略了程序文件、程序文件(x86)和用户的目录。不幸的是,我正在搜索的文件都在这些文件夹中。有人知道为什么会这样吗

任何提示都会非常有用


谢谢

您的应用程序需要以提升的权限运行,才能访问您提到的子目录中的某些子目录。作为临时测试,请以管理员身份运行以验证这一点。如果这确实是您的情况,那么您应该添加清单以在启动时要求提升


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

您的应用程序需要以提升的权限运行,以便访问您所说的子目录中的某些子目录。作为临时测试,请以管理员身份运行以验证这一点。如果这确实是您的情况,那么您应该添加清单以在启动时要求提升


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

如Jerry Dodge所提到的,安全权限当然是您需要考虑的一件事。您的代码可能需要以管理员身份运行,以便访问各种系统目录以及属于其他用户的目录。在大多数情况下,简单地枚举您提到的目录并不需要提升权限。但如果您发现遇到这样的目录,您可以:

  • 向请求提升的应用程序添加UAC清单

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

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

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

  • 错误地比较文件名。表达式
    (pos('.',SR.Name)=0)
    将适用于所有不包含
    字符的文件和目录。几乎所有文件都有
    ,甚至目录也可以有
    。在处理目录时,只需忽略特殊的
    目录条目,而不是任何包含
    的条目

  • 更糟糕的是,#1和#2的组合作用允许将具有属性的目录和包含
    的目录视为文件而不是目录。代码通常不能正确处理目录,更不用说递归了

  • 正在泄漏所有搜索句柄<如果
    FindFirst()
    成功,则必须调用code>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;
    
    使用
    系统、面具;
    过程FindFilePattern(根:字符串;模式:字符串);
    变量
    SR:TSearchRec;
    开始
    根:=包含RailingPathDelimiter(根);
    如果FindFirst(根+'*.*',faAnyFile,SR)=0,则
    尝试
    重复
    Application.ProcessMessages;
    如果(SR.Attr和faDirectory)0,则
    开始
    如果(SR.Name'')和(SR.Name'..'),则
    FindFilePattern(根+高级名称、模式);
    结束其他
    开始
    如果匹配任务(SR.名称、模式),则
    Form1.ListBox1.Items.Add(Root+SR.Name);
    结束;
    直到FindNext(SR)0;
    最后
    FindClose(SR);
    结束;
    结束;
    程序TForm1.按钮1单击(发送方:TObject);
    开始
    FindFilePattern('C:\','*.exe');
    结束;
    
    正如杰瑞·道奇(Jerry Dodge)所提到的,担保权当然是你可能需要说明的一件事。您的代码可能需要以管理员身份运行,以便访问各种系统目录以及属于其他用户的目录。在大多数情况下,简单地枚举您提到的目录并不需要提升权限。但如果您发现遇到这样的目录,您可以:

  • 向请求提升的应用程序添加UAC清单

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

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

  • 错误地比较文件属性。表达式