简体   繁体   English

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

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

I'm looking for a windows api function or another way to get the content (folder and files) of a folder located in a machine on my LAN.我正在寻找 windows api function 或其他方式来获取位于我 LAN 上的机器中的文件夹的内容(文件夹和文件)。 off course which I have a valid windows user and password for every machine which I want to access.当然,对于我想要访问的每台机器,我都有一个有效的 windows 用户和密码。

You can use the WMI, check the CIM_DataFile and CIM_Directory classes.您可以使用 WMI,检查CIM_DataFileCIM_Directory类。

Some Notes一些笔记

1.First you must enable the wmi remote access in the client machines. 1.首先您必须在客户端机器中启用 wmi 远程访问。 Read these articles to see how do this and the differences between windows versions Connecting to WMI on a Remote Computer , Securing a Remote WMI Connection .阅读这些文章,了解如何执行此操作以及 windows 版本之间的差异Connecting to WMI on a Remote ComputerSecuring a Remote WMI Connection

2.Always you must use filters (Where conditions) to restrict the result of these WMI classes. 2.始终必须使用过滤器(Where 条件)来限制这些 WMI 类的结果。

3.Always you must use the Drive field as condition, because these classes return the files of all drives. 3.始终必须使用Drive字段作为条件,因为这些类返回所有驱动器的文件。

4.The Wmi interprets the \ (Backslash) character as a reserverd symbol so you must need to escape that character to avoid problems with the WQL sentence. 4.Wmi 将\ (反斜杠)字符解释为保留符号,因此您必须对该字符进行转义以避免WQL 语句出现问题。

Delphi Code 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.

Without the authorization part, it's simple enough.没有授权部分,这很简单。 The right way to do the authorization is to call Windows.pas method WNetAddConnection2 and go that way.进行授权的正确方法是调用 Windows.pas 方法WNetAddConnection2和 go 方法。

However, because I'm in a simple hack mode, I tried this, and it basically works:但是,因为我处于简单的黑客模式,所以我尝试了这个,它基本上可以工作:

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;

Abject Apologies for the ugly hack of ShellExecute "net use".为 ShellExecute “网络使用”的丑陋黑客行为道歉。 (Grin) Note that I have elected to "mount" this shared folder without giving it a drive letter, avoiding the problem of what to do if that drive is already mapped. (Grin) 请注意,我选择“挂载”这个共享文件夹而不给它一个驱动器号,避免了如果该驱动器已经映射了该怎么办的问题。

Here's a good link with a WNetAddConnection2 code sample that I will link to instead of poaching.这是一个很好的链接,其中包含一个 WNetAddConnection2 代码示例,我将链接到该链接而不是偷猎。 It shows a sample of the non-evil way to do it.它展示了一个非邪恶方法的示例。 :-) Then you can use the Directory enumeration code as I have shown above. :-) 然后您可以使用上面显示的目录枚举代码。

I suppose this is included in Warren's answer, but to cut to the chase, IOUtils.TDirectory supports UNCs:我想这包含在 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;

etc, etc...等等等等……

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

相关问题 如何通过命令删除远程计算机中的temp文件夹的内容 - How to delete the contents of temp folder in remote machine through command 如何在PowerShell中查看远程日志文件的内容? - How can I view contents of a remote logfile in PowerShell? 如何从远程 Windows 计算机检索机器名称? - How can I retrieve the machine name from a remote Windows computer? 如何在远程计算机上启动.cmd文件? - How can I launch .cmd files on a remote machine? 如何在远程计算机上启动和停止服务? - How can I start and stop services on a remote machine? 如何获取运行maven的机器的临时文件夹? - How can I get the temp folder of a machine running maven? 无法导航到远程Linux机器上的所需文件夹,如何使用paramiko做到这一点? - Not able to navigate to desired folder on remote Linux machine, how do i do that using paramiko? 使用 Powershell 在远程计算机上创建文件夹 - 如何添加凭据? - Create folder on remote machine using Powershell - how do I add credentials? EvtExportLog API 将远程机器的事件日志保存在远程 PC 本身中。 如何将其保存到主机 PC? - EvtExportLog API is saving eventlog of remote machine in remote PC itself. How can I save it to host PC? 如何使用C#在远程Windows机器上创建共享文件夹? - How to create a shared folder on a remote Windows machine using C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM