在 Python 中获取网络位置的 DFS 路径



我想从具有分布式文件系统体系结构的Windows网络位置获得类似ping的响应,例如

path = r'\pathtosomesharedfolder_x'
delay = ping_func(path)
print delay # return response in milliseconds ?
234

一旦我有了主机,我就可以轻松地ping到位置。

我可以通过查看Windows资源管理器中的DFS选项卡来确定folder_x的主机名,该选项卡如下所示

\hostcomputer.server.ukshared$folder_x

如何在 Python 中以编程方式执行此操作?

由于您使用的是Windows,因此始终安装pywin32WMI以获取WMI函数。下面应该可以帮助您连接到远程 DFS。无法测试它,因为我没有Windows或DFS

import wmi
c = wmi.WMI (ip, user="user", password="pwd")
for share in c.Win32_Share (Type=0):
  print share.Caption, share.Path
  for session in share.associators (
    wmi_result_class="Win32_ServerConnection"
  ):
    print "  ", session.UserName, session.ActiveTime

我已经能够使用 Python 的"ctypes"模块直接调用 NetDfsGetInfo 函数。

我遇到的一些绊脚石是理解C++/Python接口和变量编组 - 这就是dfs.argtypes帮助的。

C++调用通过将指针放入您提供给调用的缓冲区来返回其结构。使用byref匹配函数原型LPBYTE *Buffer

处理输出需要定义一个与函数返回匹配的"结构",在本例中为 DFS_INFO_3 。python "buffer" 变量被强制转换为指向DFS_INFO_3的指针,ctypes.Structure定义字段名称和构建结构的类型。然后,您可以通过属性名称访问它们,例如dfs_info.EntryPath

还有一个指向可变长度数组(DFS_STORAGE_INFO(的指针,可以通过正常的Python storage[i]语法访问。

import ctypes as ct
from ctypes import wintypes as win
dfs = ct.windll.netapi32.NetDfsGetInfo
dfs.argtypes = [
    win.LPWSTR,
    win.LPWSTR,
    win.LPWSTR,
    win.DWORD,
    ct.POINTER(win.LPBYTE),
]
class DFS_STORAGE_INFO(ct.Structure):
    """Contains information about a DFS root or link target in a DFS namespace."""
    _fields_ = [  # noqa: WPS120
        ("State", win.ULONG),
        ("ServerName", win.LPWSTR),
        ("ShareName", win.LPWSTR),
    ]
class DFS_INFO_3(ct.Structure):  # noqa: WPS114
    """Contains information about a Distributed File System (DFS) root or link."""
    _fields_ = [  # noqa: WPS120
        ("EntryPath", win.LPWSTR),
        ("Comment", win.LPWSTR),
        ("State", win.DWORD),
        ("NumberOfStorages", win.DWORD),
        ("Storage", ct.POINTER(DFS_STORAGE_INFO)),
    ]
# ----- Function call -----
buffer = win.LPBYTE()  # allocate a LPBYTE type buffer to be used for return pointer
dret = dfs(r"\something.elsehere", None, None, 3, ct.byref(buffer))
# specify that buffer now points to a DFS_INFO_3 struct
dfs_info = ct.cast(buffer, ct.POINTER(DFS_INFO_3)).contents
print(dfs_info.EntryPath)
for i in range(dfs_info.NumberOfStorages):
    storage = dfs_info.Storage[i]
    print(
        f"{storage.ServerName=}",
        f"{storage.ShareName=}",
    )

相关内容

  • 没有找到相关文章

最新更新