Как получить доступ к сетевому диску через обычные классы System.IO?

Проблема заключается в круговой зависимости между модулями. a импортирует b и b импорт a. Но сначала нужно загрузить одну из них - в этом случае python завершит инициализацию модуля a до того, как b и b.hi() еще не существуют, когда вы пытаетесь получить к нему доступ в a.

14
задан Jon Seigel 28 February 2010 в 19:37
поделиться

3 ответа

Вы можете использовать UNC путь (который начинается с \\\) непосредственно в ваших путях. Однако, вы должны учитывать учетные данные для этого соединения, что может быть сложной частью.

Существует несколько подходов:

  1. Если удаленная система находится в том же домене или между доменами существуют доверительные отношения, а пользователь, от имени которого запущена ваша программа, имеет соответствующий доступ, она будет "просто работать".

  2. Вы можете выйти из системы и выполнить команду net use (через программу Windows net.exe), чтобы установить соединение с определенным именем пользователя и паролем. Имейте в виду, что соединение может быть использовано любой программой, запущенной в сеансе пользователя, а не только вашим приложением. Используйте команду /DELETE, чтобы удалить соединение, когда закончите. Типичный синтаксис следующий: net use \\\computername\sharename password /USER:domain\username.

  3. Вы можете вызвать WNetAddConnection2, чтобы выполнить то же самое, что и net use, не прибегая к net.exe. Если передать NULL в качестве lpLocalName, буква диска не назначается, но имя пользователя и пароль будут применяться к последующим доступам через путь UNC. Для разъединения можно использовать функцию WNetCancelConnection2.

  4. Вы можете выполнить P/Invoke LogonUser с флагом LOGON32_LOGON_NEW_CREDENTIALS с последующей имперсонацией для добавления дополнительных удаленных учетных данных в ваш поток. В отличие от #2 и #3, влияние на всю сессию пользователя будет немного более ограниченным. (На практике это редко делается в пользу известного решения WNetAddConnection2.)

Ниже приведен пример вызова WNetAddConnection2 из VB.NET.

Private Sub Test()
    Dim nr As New NETRESOURCE
    nr.dwType = RESOURCETYPE_DISK
    nr.lpRemoteName = "\\computer\share"
    If WNetAddConnection2(nr, "password", "user", 0) <> NO_ERROR Then
        Throw New Exception("WNetAddConnection2 failed.")
    End If
    'Code to use connection here.'
    If WNetCancelConnection2("\\computer\share", 0, True) <> NO_ERROR Then
        Throw New Exception("WNetCancelConnection2 failed.")
    End If
End Sub

<StructLayout(LayoutKind.Sequential)> _
Private Structure NETRESOURCE
    Public dwScope As UInteger
    Public dwType As UInteger
    Public dwDisplayType As UInteger
    Public dwUsage As UInteger
    <MarshalAs(UnmanagedType.LPTStr)> _
    Public lpLocalName As String
    <MarshalAs(UnmanagedType.LPTStr)> _
    Public lpRemoteName As String
    <MarshalAs(UnmanagedType.LPTStr)> _
    Public lpComment As String
    <MarshalAs(UnmanagedType.LPTStr)> _
    Public lpProvider As String
End Structure

Private Const NO_ERROR As UInteger = 0
Private Const RESOURCETYPE_DISK As UInteger = 1

<DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
Private Shared Function WNetAddConnection2(ByRef lpNetResource As NETRESOURCE, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpPassword As String, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpUserName As String, ByVal dwFlags As UInteger) As UInteger
End Function

<DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
Private Shared Function WNetCancelConnection2(<[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpName As String, ByVal dwFlags As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal fForce As Boolean) As UInteger
End Function
24
ответ дан 1 December 2019 в 09:12
поделиться

Использование обычных UNC-путей, таких как тот, который вы упомянули, отлично подходит для меня. Например:

string[] dirs = Directory.GetDirectories(@"\\192.168.1.116\");

Прекрасно работает. Если это не так, вероятно, у вас проблема с безопасностью или что-то в этом роде. В этом случае вам придется подумать о выдаче себя за другое лицо, чтобы обойти это. Проверьте этот , чтобы узнать больше о выдаче себя за другое лицо.

4
ответ дан 1 December 2019 в 09:12
поделиться

Путь UNC, который вы указали (\\\192.168.0.10\Shared Folder\MyDrive), странный. Нет никакого "диска", такой общий ресурс ведет себя как каталог. Вы бы использовали Directory.GetFiles(@"\\\192.168.0.10\Shared Folder").

1
ответ дан 1 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: