Página principal
Artículos y trucos
Catálogo de productos
Ejemplos y descargas
Mis libros
Cursos de formación
Investigación y desarrollo
Libros recomendados
Mis páginas favoritas
Acerca del autor
 
En colaboración con Amazon
 
Intuitive Sight

Diferir el borrado de ficheros

¿Ha tenido que borrar, alguna vez, un fichero que esté en uso por el sistema operativo? Uno de estos ficheros es el malévolo index.dat de la caché de Internet Explorer. Aunque limpiemos periódicamente los ficheros de la caché de IE, por alguna desconocida razón IE sigue manteniendo una copia de esos ficheros, en un directorio oculto del sistema. Con el tiempo, el tamaño consumido por la caché se desmadra, y es hora de vaciarla... pero de verdad. Es relativamente sencillo localizar el directorio y borrar todos los ficheros, excepto el mencionado index.dat. El problema es que, desde que se inicia el sistema operativo, éste abre el fichero para Dios sabe qué propósito.

La solución a éste y otros problemas similares consiste en utilizar la siguiente función del API de Windows:

function MoveFileEx(lpExistingFileName, lpNewFileName: PChar;
   dwFlags: DWORD): BOOL; stdcall;

Como indica su nombre, el propósito más general de esta función es "mover" un fichero, cambiando su nombre o el directorio en que se encuentra. Incluso puede copiar un fichero (manteniendo el original) a otro volumen de almacenamiento.

Para el uso que queremos darle, nos interesa ahora una de las constantes que se pueden incluir en el parámetro dwFlags: MOVEFILE_DELAY_UNTIL_REBOOT. Cuando se incluye esa constante, Windows, en vez de borrar el fichero inmediatamente, crea una entrada en el registro. La próxima vez que se inicia el sistema, en las operaciones de comprobación iniciales, Windows encuentra dicha entrada, realiza la operación y, como es de esperar, la elimina del registro. La clave utilizada es la siguiente:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\
   Session Manager\PendingFileRenameOperations

La función es útil, sobre todo, para programas de instalación, que muchas veces tienen que sustituir un fichero que está siendo usado por el sistema. Sin embargo, lo que nos interesa ahora es eliminar ficheros, y para ello nos basta con pasar un puntero vacío en el segundo parámetro de MoveFileEx. El siguiente procedimiento muestra cómo se puede llamar esta función del API:

procedure BorradoDiferido(const Fichero: string);
begin
   if not MoveFileEx(
      PChar(Fichero), nil, MOVEFILE_DELAY_UNTIL_REBOOT) then
      RaiseLastOSError;
end;

El único problema de MoveFileEx es que la opción de movimiento o borrado diferido sólo está implementada en Windows NT, 2000, XP y 2003. No obstante, de ser necesario el truco en Windows 9x, se puede manipular el fichero wininit.ini, para lograr el mismo efecto. Puede consultar los detalles en la ayuda del Windows SDK que viene con Delphi.