2010-02-28 7 views
13

Moje oprogramowanie obsługuje wiele operacji na plikach, a ja zakończyłem pisanie powiązanych funkcji przy użyciu klas System.IO.Jak uzyskać dostęp do dysku sieciowego za pośrednictwem zwykłych klas System.IO?

Teraz muszę dodać obsługę dysków sieciowych. Korzystanie z mapowania działa bardzo dobrze (chociaż Directory.GetFiles jest trochę niska i nie wiem dlaczego), ale chciałbym teraz móc pracować bezpośrednio z takimi ścieżkami, jak \\192.168.0.10\Shared Folder\MyDrive. Czy istnieje sposób radzenia sobie z tego typu ścieżkami innymi niż podłączenie dysku do dostępnej litery dysku, używając nowo wygenerowanej ścieżki, a następnie odmontowanie?

+0

Czy występują konkretne problemy? Nie powinno być nic innego, co trzeba zrobić, aby obsłużyć ścieżki UNC w porównaniu z mapowanymi dyskami. –

Odpowiedz

23

Możesz użyć ścieżki UNC (zaczynającej się od \\) bezpośrednio w twoich ścieżkach. Musisz jednak podać dane uwierzytelniające dla tego połączenia, co może być trudne.

Istnieją różne podejścia:

  1. Jeśli system zdalny jest w tej samej domenie lub istnieje relacja zaufania między domenami, a użytkownik program działa jak ma odpowiedniego dostępu, to będzie " po prostu pracuj".

  2. Można wykonać polecenie i wykonać polecenie net use (za pomocą programu Windows net.exe), aby nawiązać połączenie z określoną nazwą użytkownika i hasłem. Pamiętaj, że połączenie może być użyte przez dowolny program uruchomiony w sesji użytkownika, a nie tylko przez aplikację. Użyj komendy /DELETE, aby usunąć połączenie, gdy skończysz. Typowa składnia to: net use \\computername\sharename password /USER:domain\username.

  3. Możesz P/Wywołać WNetAddConnection2, aby wykonać to samo, co net use bez ostrzału na net.exe. Przekazując wartość NULL jako lpLocalName, nie jest przypisywana żadna litera dysku, ale nazwa użytkownika i hasło będą miały zastosowanie do kolejnych dostępów uzyskanych za pośrednictwem ścieżki UNC. Do rozłączenia można użyć funkcji WNetCancelConnection2.

  4. Możesz P/Wywołać LogonUser z flagą LOGON32_LOGON_NEW_CREDENTIALS, a następnie podszywać się, aby dodać dodatkowe dane logowania do swojego wątku. W przeciwieństwie do 2 i 3, efekty w całej sesji użytkownika będą nieco bardziej ograniczone. (W praktyce jest to rzadko wykonywane na rzecz znanego WNetAddConnection2 rozwiązania.)

Poniżej próbka jak zadzwonić WNetAddConnection2 z 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 
+0

+1, jest to o wiele dokładniejsze niż moja odpowiedź. –

+0

Świetnie! Wielkie dzięki :) CFP. –

3

Używanie normalnych ścieżek UNC, takich jak wymienione, działa doskonale dla mnie. Na przykład:

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

Działa dobrze. Jeśli nie, prawdopodobnie masz problem z bezpieczeństwem lub coś takiego. W takim przypadku będziesz musiał popracować nad podszywaniem się, aby to obejść. Aby uzyskać więcej informacji na temat podszywania się, sprawdź numer this.

+0

Fajnie!W rzeczywistości mój kod miał kontrolę, która przycinała ukośne ukośniki na początku ścieżki, co spowodowało błąd, gdy próbowałem tego. Dzięki! CFP. –

1

Opublikowana ścieżka UNC (\\192.168.0.10\Shared Folder\MyDrive) jest nieparzysta. Nie ma "dysku", taki udział zachowuje się jak katalog. Używałbyś Directory.GetFiles(@"\\192.168.0.10\Shared Folder").

Powiązane problemy