2010-12-15 16 views
7

¿Hay alguna forma de tener un descanso de sesión de depuración de VS cuando se lee o escribe un archivo específico?Puntos de interrupción de Visual Studio: interrupción en el acceso a archivos específicos

En este caso, me gustaría utilizarlo como una herramienta de exploración, supongamos que no sé en qué parte de un código grande se está accediendo a este archivo, o donde se está configurando el nombre del archivo, podría ser recogido desde el fondo en algunas configuraciones a gran escala.

Respuesta

3

Lo que haría es piratear rápidamente una clase estática que usa FileSystemWatcher class para escuchar archivos crear/cambiar eventos, y poner un punto de interrupción en la devolución de llamada de evento, o llama al System.Diagnostics.Debugger.Break allí.

Luego, cuando se rompe, cambie a la ventana de Subprocesos e intente localizar el subproceso y el fragmento de código que hizo el acceso real al archivo.

Si necesita usar esto mucho, solicite a esta clase que mantenga una lista de los nombres de archivo específicos que desea romper, y exponga dos métodos públicos estáticos: Para Comenzar y Detener la escucha de cambios en un archivo específico.

Además, si tiene VS2010 Ultimate, simplemente puede buscar a través de la lista de eventos File Created en el registro de eventos de IntelliTrace.

+0

No lo he probado, pero es muy posible que sea genial. Estaba pensando en FileSystemWatcher ayer, deseando que hubiera alguna forma de conectarlo. Buena idea, lo intentaré. –

0

Puede establecer un punto de interrupción condicional.

Supongamos que tiene una variable de cadena strFileName donde se almacena el nombre del archivo.

En la línea donde se lee el archivo, establezca un punto de interrupción. Haga clic derecho en el punto de interrupción y haga clic en "Condición ...".

En el diálogo de hacer:

strFileName = "TheSpecificFileName.txt" 

que haría el trabajo si el nombre del archivo está disponible que se está leyendo.

+1

Gracias - pero estoy asumiendo que no sé donde en una gran base de código se está accediendo a este archivo desde o donde se está configurando el nombre del archivo - se puede recoger desde el fondo en algunas configuraciones a gran escala. –

1

Actualmente mi proceso tiene que ser:

  • Buscar en archivos para el nombre de archivo o un nombre de archivo parcial
  • Encuentre en archivos de configuración para el nombre de archivo o un nombre de archivo parcial
  • Guess al objeto de nombre de archivo o contenido, encontrar el objeto en el código base, rompen en las entradas método
  • (si xml, romper el ReadXml para averiguar dónde se abrió ...)

que es torpe pero funciona ...

3

Si está interesado en cualquier acceso al archivo, en lugar de solo escribir en él, FileSystemWatcher no ayudará.

Una solución simple es abrir el archivo con anticipación y esperar a que la otra lógica acceda a él, activando un IOException. Se puede utilizar la siguiente clase de ayuda para romper de inmediato - o característica "Excepción de primera oportunidad" de VS:

using System; 
using System.Diagnostics; 
using System.IO; 
using System.Threading; 

static class DebugHelper 
{ 
    public static void BreakOnFileAccess(string path) 
    { 
     var msg = Path.GetFullPath(path); 
     msg = "The process cannot access the file '" + msg; 
     msg = msg.ToUpper(); 

     var fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); 
     new Thread(() => { 
      while (true) 
      { 
       Thread.Sleep(Timeout.Infinite); 
       // ensure FileStream isn't GC'd as a local variable after its last usage 
       GC.KeepAlive(fs); 
      } 
     }).Start(); 

     AppDomain.CurrentDomain.FirstChanceException += (sender, e) => { 
      if (e.Exception is IOException && 
       e.Exception.Message.ToUpper().Contains(msg)) 
      { 
       Debugger.Break(); 
      } 
     }; 
    } 
} 
+0

Gracias, especialmente por recoger tanto tiempo después de que se hizo la pregunta. ¿Por qué GC.KeepAlive? ¿Tener un identificador fs estático o una lista de identificadores tiene el mismo efecto? –

+1

La llamada a KeepAlive es para asegurarse de que FileStream no tenga GC, ya que no se garantiza que las variables locales permanezcan activas después de su último uso en el método. Sí, mantener una referencia en un campo estático o una colección serviría igual de bien :-) – staafl

Cuestiones relacionadas