Получите путь DFS сетевого расположения в Python

Я хочу получить ping-подобный ответ из сетевого расположения Windows, которое имеет архитектуру распределенной файловой системы, например

path = r'\\path\to\some\shared\folder_x'
delay = ping_func(path)
print delay # return response in milliseconds ?
234

Когда у меня есть хост-компьютер, я могу легко проверить связь с местоположением.

Я могу определить имя хоста для folder_x глядя на вкладку DFS в проводнике Windows, который будет выглядеть, например, например,

\\hostcomputer.server.uk\shared$\folder_x

Как я могу сделать это программно в Python?

2 ответа

Я смог напрямую позвонитьNetDfsGetInfoфункция с использованием модуля Python "ctypes".

Некоторые точки преткновения, которые у меня были, заключались в понимании интерфейса C++/Python и маршалинга переменных — вот чтоdfs.argtypesпомогает с.

Вызовы C++ возвращают свои структуры, помещая указатели в буфер, который вы предоставляете вызову. С использованиемbyrefвы соответствуете прототипу функцииLPBYTE *Buffer

Обработка вывода требует определения «Структуры», которая соответствует возвращаемой функции, в данном случае . Переменная python «buffer» приводится как указатель наDFS_INFO_3иctypes.Structureопределяет имена полей и типы, из которых строится структура. Затем вы можете получить к ним доступ через имя атрибута, например,dfs_info.EntryPath

Был указатель на массив переменной длины (DFS_STORAGE_INFO) тоже возвращается, к которому можно получить доступ через обычный Pythonstorage[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.else\here", 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=}",
    )

Поскольку вы используете Windows, ваша установка всегда pywin32 а также WMI чтобы получить функции 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
Другие вопросы по тегам