繁体   English   中英

如何列出远程计算机文件夹的内容

[英]How I can list the contents of a folder of a remote machine

我正在寻找 windows api function 或其他方式来获取位于我 LAN 上的机器中的文件夹的内容(文件夹和文件)。 当然,对于我想要访问的每台机器,我都有一个有效的 windows 用户和密码。

您可以使用 WMI,检查CIM_DataFileCIM_Directory类。

一些笔记

1.首先您必须在客户端机器中启用 wmi 远程访问。 阅读这些文章,了解如何执行此操作以及 windows 版本之间的差异Connecting to WMI on a Remote ComputerSecuring a Remote WMI Connection

2.始终必须使用过滤器(Where 条件)来限制这些 WMI 类的结果。

3.始终必须使用Drive字段作为条件,因为这些类返回所有驱动器的文件。

4.Wmi 将\ (反斜杠)字符解释为保留符号,因此您必须对该字符进行转义以避免WQL 语句出现问题。

Delphi 代码

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

procedure  GetRemoteFolderContent(Const WbemComputer,WbemUser,WbemPassword,Path:string);
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;    
  WmiPath       : string;
  Drive         : string;
begin;
  //The path  
  //Get the drive 
  Drive   :=ExtractFileDrive(Path);
  //get the path and add a backslash to the end
  WmiPath :=IncludeTrailingPathDelimiter(Copy(Path,3,Length(Path)));
  //escape the backslash character
  WmiPath :=StringReplace(WmiPath,'\','\\',[rfReplaceAll]);

  Writeln('Connecting');
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  //Establish the connection
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);

  Writeln('Files');
  Writeln('-----');
  //Get the files from the specified folder
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT * FROM CIM_DataFile Where Drive="%s" AND Path="%s"',[Drive,WmiPath]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('%s',[FWbemObject.Name]));
    FWbemObject:=Unassigned;
  end;

  Writeln('Folders');
  Writeln('-------');
  //Get the folders from the specified folder
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT * FROM CIM_Directory Where Drive="%s" AND Path="%s"',[Drive,WmiPath]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('%s',[FWbemObject.Name]));
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetRemoteFolderContent('remote_machine','user','password','C:\');
      GetRemoteFolderContent('remote_machine','user','password','C:\Program Files');
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

没有授权部分,这很简单。 进行授权的正确方法是调用 Windows.pas 方法WNetAddConnection2和 go 方法。

但是,因为我处于简单的黑客模式,所以我尝试了这个,它基本上可以工作:

uses Types, IOUtils, ShellApi; // Works in Delphi XE.

procedure TForm5.Button1Click(Sender: TObject);
var
 dirs:TStringDynArray;
 files:TStringDynArray;
 apath, dir,filename:String;
begin
 ListBox1.Items.Clear;
 apath := '\\hostname\sharename';

// This should be calling WNetAddConnection2:
// instead It's an evil (portable) hack.
 ShellExecute(HWND(0), 'open', PChar('net use /delete '+  apath), 
    nil,nil,SW_SHOW );
 ShellExecute(HWND(0), 'open', PChar('net use '+ apath+' /user:uid pswd'),
    nil,nil,SW_SHOW );

  dirs := TDirectory.GetDirectories(apath);
  if Length(dirs)=0 then
      ListBox1.Items.Add('None found.')
  else
  for dir in dirs do
      ListBox1.Items.Add('Directory: '+dir);
  files := TDirectory.GetFiles(apath);
  for filename in files do
      ListBox1.Items.Add('File: '+filename );

end;

为 ShellExecute “网络使用”的丑陋黑客行为道歉。 (Grin) 请注意,我选择“挂载”这个共享文件夹而不给它一个驱动器号,避免了如果该驱动器已经映射了该怎么办的问题。

这是一个很好的链接,其中包含一个 WNetAddConnection2 代码示例,我将链接到该链接而不是偷猎。 它展示了一个非邪恶方法的示例。 :-) 然后您可以使用上面显示的目录枚举代码。

我想这包含在 Warren 的回答中,但切入正题, IOUtils.TDirectory支持 UNC:

implementation
uses IOUtils,types;

procedure GetFiles;
var
  i: integer;
  files: TStringDynArray;
begin
  files := TDirectory.GetFiles('\\aServer\aPath\aShare\', '*.aFileFilter');
  for i := Low(files)to High(files) do
       memo1.Lines.Add(files[i]);
end;

等等等等……

暂无
暂无

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

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