2011-12-25 21 views
7

Tratamos de tener acceso a un directorio que está dentro de un directorio de red, pero obtener resultados erróneos (C#/Windows):Cómo forzar a Windows para volver a conectar a la unidad de red

var exists = Directory.Exists("Z:\\Sessions\\Data1"); 

"Z" es el directorio de red " Sesiones "es un directorio donde un software de grabación constantemente crea directorios (por ejemplo," Datos1 ") y pone algunos datos en él. Parece que Windows almacena en caché el estado incorrecto sobre Data1: el método devuelve falso. Pero cuando accedo al directorio a través de Explorer, está aquí. Cuando ejecuto el método (Directory.Exists) después de acceder al directorio con Explorer, devuelve verdadero. Por supuesto, puedo garantizar que el directorio realmente existe en el primer intento.

¿Cuál es la razón de este comportamiento? ¿Qué puedo hacer al respecto?

Editar: Parece que Windows no pudo conectar la unidad de red a la computadora remota. Cuando trato de navegar en el directorio con Explorer, automáticamente intenta conectar la unidad.

Así que la pregunta cambia: ¿Hay alguna manera de forzar las ventanas para intentar una reconexión a través de .NET?

Solución: Reconnecting a disconnected network drive

+0

Si accede al directorio con el comando 'DIR' desde el símbolo del sistema, ¿obtiene la información correcta? Es decir: 'dir Z: \ Sesiones \ Datos1'. –

+0

No, acceder al directorio mediante el símbolo del sistema no actualiza la conexión de la unidad de red. Por favor, vea mi edición ... – nepa

Respuesta

0

¿Cuál es la razón de este comportamiento?

Presupuesto de la documentation:

Si usted no tiene a un solo permiso de lectura en el directorio, mínimo EXISTS método devolverá falso.


¿Qué puedo hacer al respecto?

Asegúrese de que está ejecutando su aplicación .NET en una cuenta que tenga al menos permiso de solo lectura para acceder a esta carpeta. Tenga en cuenta que si escribe esto en una aplicación ASP.NET, probablemente este no sea el caso, de modo que, según la cuenta en la que configuró su servidor web para ejecutar la aplicación, siga los pasos necesarios para otorgar permisos a esta cuenta.

+0

como el OP mencionó, "Cuando ejecuto el método (Directory.Exists) después de acceder al directorio con Explorer, devuelve true." - lo que significa que lo más probable es que sea un problema de almacenamiento en caché en lugar de Permisos –

+1

@ EugeneMayevski'EldoSCorp, cuando usa el Explorer lo está ejecutando bajo su cuenta. Cuando ejecuta una aplicación ASP.NET, podría ejecutarse bajo una cuenta completamente diferente. Así que supongo que la prueba que realizó el OP para verificar que existe el directorio no se realizó en las mismas condiciones: en el primer caso utilizó su propia cuenta, mientras que en el segundo se usó otra cuenta (solo pudimos adivinar cuál en esta etapa, ya que OP proporcionó exactamente 0 contextos sobre su aplicación). –

+0

La pregunta cambió debido a algunos descubrimientos que hice, por favor vea mis ediciones. – nepa

2

Yo también uso un disco remoto y me lleva unos segundos conectarlo, así que solo espero y trabajo todo el tiempo. Si no se conecta, enviará un correo electrónico y yo lo verificaré.

 logger.Info("Create Z: drive "); 
     System.Diagnostics.Process process = new System.Diagnostics.Process(); 
     System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 
     startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
     startInfo.FileName = "cmd.exe"; 
     startInfo.Arguments = @"/C net use z: \\" + Tools.servername + @"\SHARE_NAME_HERE /user:USER_NAME_HERE PASSWORD_HERE"; 
     process.StartInfo = startInfo; 
     process.Start(); 
     logger.Info("Z: drive created "); 

     // wait get Z: 
     int xtimestimeout = 5; 
     while (!Directory.Exists(@"Z:\") & (xtimestimeout > 0)) 
     { 
      Application.DoEvents(); 
      SetBalloonTip(@"Program", @"connecting... please wait"); 
      ShowBalloon(); 
      logger.Info("Creating Z:... waiting..."); 
      Application.DoEvents(); 
      System.Threading.Thread.Sleep(3000); 
      xtimestimeout -= 1; 
     } 

     // check for sucessfull creation of Z: in server Z:\somedirectory 
     if (!Directory.Exists(@"Z:\")) 
     { 
      SendEmail2("Oh my... help!", "drive Z: not created <<< CHECK!"); 
      logger.Info("Z: email sent because of not created"); 
     } 
     logger.Info("Z: drive created successfully."); 
+0

Bueno, alguien marca mi respuesta con -1. No entiendo POR QUÉ porque yo también tengo la misma situación que la pregunta y este código lo resuelve. Este código funciona y solo usa el código .net, no la biblioteca externa como la respuesta que se marcó como solución. –

+0

No te preocupes, lo contrario lo voté. Es realmente una buena solución, exactamente lo que estoy tratando de hacer. Pero tampoco quiero que aparezca la ventana de cmd. Sin embargo, no he probado tu código, pero parece prometedor. Gracias. – xmen

1

no estoy seguro de qué versión de mpr.dll el enlace anterior solución trabaja con, pero yo estoy usando Win7 y tienen una versión ligeramente diferente (aunque similar). Este punto de entrada es:

[DllImport("mpr.dll", SetLastError = true, EntryPoint = "WNetRestoreSingleConnectionW", CharSet = CharSet.Unicode)] 
    internal static extern int WNetRestoreSingleConnection(IntPtr windowHandle, 
                  [MarshalAs(UnmanagedType.LPWStr)] string localDrive, 
                  [MarshalAs(UnmanagedType.Bool)] bool useUI); 

a continuación:

IntPtr hWnd = new IntPtr(0); 
int res = WNetRestoreSingleConnection(hWnd, <your drive path>, false); 

Vas a tener que añadir su propia comprobación de errores/manipulación.

Cuestiones relacionadas