2010-02-28 24 views
13

Mi software maneja múltiples operaciones en archivos, y ahora he terminado de escribir las funciones relacionadas, usando las clases System.IO.¿Cómo accedo a una unidad de red a través de las clases habituales de System.IO?

Ahora necesito agregar soporte para unidades de red. Usar una asignación funciona muy bien (aunque Directory.GetFiles es un poco bajo, y no sé por qué), pero ahora me gustaría poder tratar directamente con rutas como \\192.168.0.10\Shared Folder\MyDrive. ¿Hay alguna forma de manejar este tipo de rutas además de montar la unidad en una letra de unidad disponible, usando la ruta recién generada, y luego desmontarla?

+0

¿Estás experimentando problemas específicos? No debería haber nada diferente que deba hacer para manejar rutas UNC frente a unidades mapeadas. –

Respuesta

23

Puede usar la ruta UNC (que comienza con \\) directamente en sus rutas. Sin embargo, debe tener en cuenta las credenciales para esta conexión, que puede ser la parte difícil.

Existen varios enfoques:

  1. Si el sistema remoto está en el mismo dominio o existe una relación de confianza entre los dominios, y el usuario el programa se ejecuta al igual que el acceso adecuado, lo hará " solo trabajo".

  2. Puede pagar y ejecutar el comando net use (a través del programa Windows net.exe) para establecer una conexión con un nombre de usuario y contraseña específicos. Tenga en cuenta que cualquier programa que se ejecute en la sesión del usuario puede usar la conexión, no solo su aplicación. Use el comando /DELETE para eliminar la conexión cuando haya terminado. La sintaxis típica es: net use \\computername\sharename password /USER:domain\username.

  3. Puede P/Invocar WNetAddConnection2 para lograr lo mismo que net use sin descascarar a net.exe. Al pasar NULL como lpLocalName, no se asigna ninguna letra de unidad, pero el nombre de usuario y la contraseña se aplicarán a los accesos posteriores realizados a través de la ruta UNC. La función WNetCancelConnection2 se puede usar para desconectar.

  4. Puede P/Invoke LogonUser con la bandera LOGON32_LOGON_NEW_CREDENTIALS seguido de una suplantación de añadir credenciales remotas adicionales a su hilo. A diferencia de los números 2 y 3, los efectos en la sesión completa del usuario serán un poco más limitados. (En la práctica, esto rara vez se hace en favor de la solución conocida WNetAddConnection2.)

El siguiente es un ejemplo de cómo llamar a WNetAddConnection2 de 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, esto es mucho más exhaustivo que mi respuesta. –

+0

¡Genial! Muchas gracias :) CFP. –

3

El uso de rutas UNC normales como la que mencionó me funciona perfectamente. Por ejemplo:

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

Funciona bien. Si no es así, probablemente tengas un problema de seguridad o algo así. En ese caso, tendrás que buscar una suplantación para evitar eso. Consulte this para obtener más información sobre la suplantación.

+0

¡Genial!De hecho, mi código tenía una marca que cortaba las barras invertidas al comienzo de la ruta, lo que provocó un error cuando probé esto. Gracias! CFP. –

1

La ruta UNC que publicó (\\192.168.0.10\Shared Folder\MyDrive) es impar. No hay "unidad", tal acción se comporta como un directorio. Utilizarías Directory.GetFiles(@"\\192.168.0.10\Shared Folder").

Cuestiones relacionadas