No se si te das cuenta de la cantidad de conocimientos que se requieren para llevar a cabo esta tarea, además de la experiencia en intentos fallidos, si ...porque hookear APIS es lo que tiene, que por alguna chorrada insignificante un hook puede ir perféctamente en Windows XP, pero no funcionar en otra versión de Windows, y lo mismo con las arquitecturas, además entre las diferentes versiones de windows pueden modificar los parámetros de "X" funciones. Fíjate si es dificil que resulta necesario utilizar librerías de terceros para realizar estos hooks de forma decente los cuales ya se encargan de inyectar y etc...
Este campo no lo he tocado prácticamente
nada, no vayas a pensar que soy un experto en el tema, los únicos hooks que he realizado han sido de bajo nivel con las funciones que la WinAPI proporciona para instalar los hooks, pero a lo que voy ...implementar
ICopyHook sería una manera más limpia (y estable) sin necesidad de Hookear, y te permitiria tener control sobre los archivos eliminados desde el Explorer, pero sigue siendo una pesadilla llevarlo a cabo.
Ahora bien, hay otra alternativa mucho más facil que se me ha ocurrido, sirviéndote del
FileSystemWatcher. No pongo la mano en el fuego de haberlo dejado 100% efectivo, deberías testear en profundidad lo que sucede cuando eliminas dos archivos/carpetas con el mismo nombre pero con distinta fecha de modificación para comprobar si se restaura la que se debe restaurar, yo solo te dejo la idea:
EDITO: Para proceder a usar el siguiente código necesitas referenciar
Microsoft Shell Controls And Automation.
EDITO2: Le añadí un par de cosas más, y también lo documenté un poco mejor...
Imports System.IO
Imports Shell32
Public Class Test
Private SH As New Shell
Private RecycleBin
As Folder = SH.
NameSpace(ShellSpecialFolderConstants.
ssfBITBUCKET) Private WithEvents FSW As New FileSystemWatcher
Private Shadows Sub Load() _
Handles MyBase.Load
' Seteo las propiedades del objeto 'FileSystemWatcher'.
With FSW
.Path = "C:\Test"
.IncludeSubdirectories = True
.Filter = "*"
.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.DirectoryName
.EnableRaisingEvents = True
End With
End Sub
Private Sub OnItemDeleted(sender As FileSystemWatcher, e As FileSystemEventArgs) _
Handles FSW.Deleted
' Almacenamos una colección de los items de la papelera de reciclaje.
' Tanto archivos, carpetas, y accesos directos .lnk (que no se tratan como archivos ni carpetas),
' cuyo nombre sea el mismo nombre que el elemento que se acaba de eliminar.
' Y los ordenamos por su fecha de modificación.
Dim DeletedItems As IEnumerable(Of FolderItem) =
RecycleBin.Items.Cast(Of FolderItem).
Where(Function(Item) Item.Name = e.Name).
OrderBy(Function(Item) Item.ModifyDate)
' Si hubiera más de un elemento con el mismo nombre,
' seleccionamos el último elemento que se eliminó (o al menos, eso se supone que debería suceder.)
Dim LastDeletedItem As Shell32.FolderItem = DeletedItems.LastOrDefault
If LastDeletedItem IsNot Nothing Then
' Esto es un simple checkeo por prevención,
' considero que solo hay un 0,00001% de posibilidades de que se de la condición...
' Esto podría deberse a que el usuario haya desecho manuálmente la acción de borrado (CTRL+Z),
' en un tiempo menor del que la aplicación ha procesado los elementos de la papelera.
'
' También está el caso de las incontrolables acciones de terceros,
' Como por ejemplo el editor de texto 'Sublime Text', que al modificar un archivo,
' lo elimina dando un falso positivo.
If (LastDeletedItem.IsFolder AndAlso Directory.Exists(e.FullPath)) _
OrElse
(Not LastDeletedItem.
IsFolder AndAlso File.
Exists(e.
FullPath)) Then
Throw New Exception(String.Format("¿ El elemento ha sido restaurado ?: {0}", e.FullPath))
Exit Sub
End If
' Invocamos el verbo "undelete" para deshacer la acción de borrado sin necesidad de escribir más isntrucciones.
' Otros verbos que se pueden usar por ejemplo "delete" para eliminar el elemento de forma permanente,
' u "open" para abrir las propiedades del elemento.
LastDeletedItem.InvokeVerb("undelete")
' O bien hacemos otra cosa distinta, como por ejemplo un backup del archivo/directorio eliminado...
'
'Dim BackupPath = String.Format("C:\Backup\{0}", e.Name)
'
'Select Case LastDeletedItem.IsFolder
'
' Case True
' FileIO.FileSystem.CopyDirectory(LastDeletedItem.Path, BackupPath,
' FileIO.UIOption.AllDialogs, FileIO.UICancelOption.ThrowException)
'
' Case False
' FileIO.FileSystem.CopyFile(LastDeletedItem.Path, BackupPath,
' FileIO.UIOption.AllDialogs, FileIO.UICancelOption.ThrowException)
'
'End Select
End If
End Sub
End Class
Saludos