2010-02-28 15 views
13

Il mio software gestisce più operazioni sui file, e ora ho finito di scrivere le relative funzioni, usando le classi System.IO.Come accedere a un drive di rete attraverso le solite classi System.IO?

Ora è necessario aggiungere il supporto per le unità di rete. L'utilizzo di una mappatura funziona molto bene (anche se lo standard Directory.GetFiles è un po 'basso, e non so perché), ma ora mi piacerebbe essere in grado di gestire direttamente percorsi come \\192.168.0.10\Shared Folder\MyDrive. Esiste un modo per gestire questo tipo di percorsi se non montando l'unità su una lettera di unità disponibile, utilizzando il percorso appena generato e quindi smontando?

+0

Stai riscontrando problemi specifici? Non ci dovrebbe essere nulla di diverso che devi fare per gestire i percorsi UNC e le unità mappate. –

risposta

23

È possibile utilizzare il percorso UNC (che inizia con \\) direttamente nei percorsi. Tuttavia, è necessario tenere conto delle credenziali per questa connessione, che può essere la parte difficile.

Ci sono diversi approcci:

  1. Se il sistema remoto è sullo stesso dominio o v'è una relazione di trust tra i domini, e l'utente il programma è in esecuzione come ha accesso adeguato, lo farà " solo lavoro".

  2. È possibile eseguire il shell out ed eseguire il comando net use (tramite il programma Windows net.exe) per stabilire una connessione con un nome utente e una password specifici. Tieni presente che la connessione è utilizzabile da qualsiasi programma in esecuzione nella sessione dell'utente, non solo dalla tua applicazione. Utilizzare il comando /DELETE per rimuovere la connessione al termine. La sintassi tipica è: net use \\computername\sharename password /USER:domain\username.

  3. È possibile P/Richiamare WNetAddConnection2 per eseguire la stessa cosa di net use senza eseguire il bombardamento su net.exe. Passando NULL come lpLocalName, non viene assegnata alcuna lettera di unità, ma il nome utente e la password verranno applicati agli accessi successivi effettuati tramite il percorso UNC. La funzione WNetCancelConnection2 può essere utilizzata per disconnettersi.

  4. È possibile P/Richiamare LogonUser con il flag LOGON32_LOGON_NEW_CREDENTIALS seguito da una rappresentazione per aggiungere credenziali remote aggiuntive al thread. A differenza di # 2 e # 3, gli effetti sull'intera sessione dell'utente saranno un po 'più limitati. (In pratica, ciò avviene raramente in favore del ben noto WNetAddConnection2 soluzione.)

Il seguente è un esempio di come chiamare WNetAddConnection2 da 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, questo è molto più accurato della mia risposta. –

+0

Ottimo! Grazie mille :) CFP. –

3

L'utilizzo di normali percorsi UNC come quello che hai citato funziona perfettamente per me. Ad esempio:

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

Funziona bene. In caso contrario, probabilmente hai un problema di sicurezza o qualcosa del genere. In tal caso, dovrai indagare sull'imitazione per aggirare questo problema. Controlla this per ulteriori informazioni sulla rappresentazione.

+0

Fantastico!In effetti il ​​mio codice ha avuto un controllo che ritagliava i backslash all'inizio del percorso, che causava un bug quando lo provavo. Grazie! CFP. –

1

Il percorso UNC che hai postato (\\192.168.0.10\Shared Folder\MyDrive) è dispari. Non esiste un "drive", una tale condivisione si comporta come una directory. Dovresti usare Directory.GetFiles(@"\\192.168.0.10\Shared Folder").