Los archivos están en un estado de cambio constante en cualquier sistema operativo. A veces se crean, a veces se eliminan, a veces se cambian, y todas esas son cosas normales que debe hacer un sistema operativo. A veces, cuando se cambia un archivo, puede causar inestabilidad en otra aplicación que depende de él, como cambiar un número de puerto en un archivo de propiedades, un parámetro en un manifiesto de implementación o inclusive corregir el código en producción sin pasar por el control de fuente.
Como parte de la administración de estos sistemas operativos, los ingenieros necesitan una forma de observar lo que sucede con estos archivos críticos y tomar medidas cuando algo sucede. Ingrese al .NET Clase FileSystemWatcher y PowerShell.
En .NET y .NET Core, FileSystemWatcher es una clase que vive en el System.IO espacio de nombres y supervisa archivos. En PowerShell, esto puede ser muy útil, especialmente cuando se combina con otras funciones de PowerShell.
Creación de instancias de FileSystemWatcher
Cree una instancia de esta clase en PowerShell ejecutando $watcher = New-Object System.IO.FileSystemWatcher
. Una vez que lo haga, deberá indicarle qué carpeta debe mirar. Puede hacer esto configurando el Sendero en el objeto FileSystemWatcher a la ruta de la carpeta que desee ver. Si dispone de una carpeta en Windows llamada WatchThisFolder debajo C:, debe configurar FileSystemWatcher en eso ejecutando $watcher.Path="C:WatchThisFolder"
.
Debido a que esta clase además está en .NET Core, puede hacer todo esto en un sistema Linux o Mac OS de la misma manera que lo haría en un sistema Windows. A modo de ejemplo, si tuviera una carpeta en Ubuntu Linux llamada WatchThisFolder bajo su directorio de usuario actual, debería ejecutar $watcher.Path="/home/ubuntu/WatchThisFolder"
.
El resto de los ejemplos de código de este post funcionan en cualquiera de las plataformas sin ningún cambio.
Activación de eventos desde FileSystemWatcher
Ahora que tiene un nuevo objeto FileSystemWatcher, puede echar un vistazo debajo del capó e intentar averiguarlo. Para ver los tipos específicos de eventos del sistema de archivos que está observando FileSystemWatcher, ingrese $watcher | Get-Member -MemberType Event
. Obtener miembro muestra todo lo que contiene el objeto que le ha pasado y, al agregar el filtro MemberType, puede ver una categoría determinada, en esta circunstancia, eventos.
Esos eventos son:
- Cambió
- Creado
- Eliminado
- Dispuesto
- Error
- Renombrado
Cuando se detecta uno o más de estos eventos FileSystemWatcher en la ruta que el objeto está configurado para observar, el objeto observador genera un evento externo, para el cual puede establecer acciones.
Ahora que el objeto del observador sabe qué mirar y usted sabe qué eventos está observando, debe configurarlo para que genere un evento cuando se detecte una acción. Haz esto corriendo $watcher.EnableRaisingEvents = $true
. Piense en esta bandera como un interruptor de encendido / apagado para $watcher
: Si el interruptor está apagado, no sucederá nada si se realizan cambios. Además puede decirle que mire los archivos y carpetas anidados debajo del conjunto en la ruta cambiando el Incluir subdirectorios la bandera a verdadera de la misma manera que hiciste el EnableRaisingEvents bandera.
Definición de acciones a tomar
Una vez que se configura el objeto del observador, debe darle una acción para que la realice una vez que se detecte ese cambio. Esto puede ser tan simple como escribir en un registro del sistema, o tan drástico como activar un reemplazo de la instancia con una extracción limpia del código fuente. Para comenzar, debe establecer un bloque de acción en el código. Aquí hay uno que solo escribe en la consola:
$action = { $path = $event.SourceEventArgs.FullPath $name = $event.SourceEventArgs.Name $changetype = $event.SourceEventArgs.ChangeType Write-Host "File $name at path $path was $changetype at $(get-date)" }
Puede ver que este código está extrayendo variables del evento usando el $event
variable, que se crea automáticamente cuando el objeto del observador crea el evento. Tan pronto como termina el evento, la variable además termina, lo que significa que solo tendrá datos relevantes para ese evento.
Usando el Register-ObjectEvent
Entonces, tiene configurado FileSystemWatcher y tiene acciones que desea tomar cada vez que sucede algo. En este momento, estos dos están separados y no se conocen. Para que trabajen juntos, debe registrar las acciones con el evento. PowerShell tiene un cmdlet completo para esto: el Register-ObjectEvent cmdlet. Para utilizar Register-ObjectEvent, debe pasarle tres cosas:
- El objeto FileSystemWatcher
- El tipo de evento para desencadenar las acciones en
- Las acciones que definiste previamente
Si ha configurado todo de la misma manera que se enumera previamente, se verá así: Register-ObjectEvent $watcher 'Event Action' -Action $action.
‘Event Action’ se puede reemplazar con cualquier evento del FileSystemWatcher, pero esto será una buena demostración.
Probándolo
Ahora puedes probarlo todo. En esta sección, creará un nuevo archivo en el directorio especificado, verá la acción del evento, posteriormente deshabilitará y anulará el registro del evento.
Para crear un nuevo archivo y desencadenar el evento, ejecute la próxima línea en PowerShell. Esto es en Ubuntu Linux, pero si lo está siguiendo en Windows, reemplace / inicio / ubuntu / con C: y / con .
New-Item -Path "/home/ubuntu/WatchThisFolder/newFile" -ItemType File
Tan pronto como ingrese eso, el evento se dispara y la acción se dispara.
File newFile at path /home/ubuntu/WatchThisFolder/newFile was Created at 09/26/2019 20:49:54
Se dispara cada vez que crea un nuevo archivo en ese directorio o cualquier cosa anidada debajo de él, si habilitó el Incluir subdirectorios bandera. Ahora que sabe que incrementar el evento funciona, apáguelo ejecutando $watcher.EnableRaisingEvents = $false
, posteriormente intente crear un nuevo archivo. Se debe crear el archivo, pero no se muestra ningún evento. Esto puede resultar muy útil si está depurando y no desea activar nada mientras trabaja en el sistema de archivos.
Una vez que haya terminado, ejecute Get-EventSubscriber | Unregister-Event
para anular el registro del evento de la acción. Ahora, inclusive si la marca EnableRaisingEvents es verdadera y la acción ocurre, la acción no se activará.