Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-12-2008
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Como saber si un fichero está abierto

Buenas!

Tengo que mover de directorio una serie de ficheros (algunos son word, un fdb, varios ini's...) pero antes de hacerlo, necesito saber si alguno de esos ficheros están abiertos por otra aplicación antes de moverlos de directorio.

Sabéis si hay alguna función que devuelva el estado del fichero?

Muchas gracias.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #2  
Antiguo 03-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
¿Ya usaste la búsqueda del foro?

http://www.clubdelphi.com/foros/showthread.php?t=48717
Responder Con Cita
  #3  
Antiguo 04-12-2008
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Mi problema no es saber si un programa está en ejecución, es saber si un fichero (.doc, .fdb, .ini....) está abierto.

El directorio que quiero mover es el directorio donde se encuentra la base de datos de otra aplicación nuestra. Si la base de datos está abierta, ya sea por la aplicación o por el IBExpert, no debo intentar moverla, al igual que el resto de ficheros que hay en el mismo directorio.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #4  
Antiguo 04-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
Buscando un poco en la internet, se encuentran algunas funciones interesantes

http://mc-computing.com/languages/De...lphiFileIO.htm
También algo sobre el manejo de las excepciones:
http://zarza.fis.usal.es/~fgarcia/do...bajos/S2T5.pdf

Quizá te sirvan mientras
Responder Con Cita
  #5  
Antiguo 04-12-2008
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

En realidad a mí me parece que no hay forma de saber si un archivo está abierto o qué, a no ser que la aplicación que lo abra lo haga "de forma exclusiva". En este caso tal vez uno podría comprobar si el archivo, efectivamente, fue abierto de esa forma, dicho mal y pronto. Pero, si la aplicación que abre un archivo (y es lo normal) no lo abre de forma exclusiva, ya digo, puedo estar equivocado, pero, ¿cómo podría averiguarse que el archivo en cuestión está abierto?

Te pondré un ejemplo. Una aplicación de Delphi cuenta con un "TMemo" en el que carga el contenido de un archivo. La aplicación lee el archivo, y pone su contenido en el "TMemo". Y ahí se acaba todo. El archivo puede incluso eliminarse a continuación, que, el contenido del mismo seguirá en el "TMemo". Si otra aplicación quiere saber si la mía abrió el archivo de marras, ¿cómo iba a hacerlo?
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 04-12-2008 a las 17:34:51.
Responder Con Cita
  #6  
Antiguo 04-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
Yo pensé en los atributos del documento en ese momento... como cuando abres dos veces un archivo de excell te dice en "modo de solo lectura", quizá el se refiera a eso...
Responder Con Cita
  #7  
Antiguo 04-12-2008
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

No sabía de esto último que dices Felipe. Aunque, probablemente, Excel abra el archivo "de forma exclusiva", y así luego puede averiguar si el archivo está abierto de esa forma: aunque sea por la propia aplicación, de modo que lo abra como "sólo lectura". Lo cierto es que tampoco te creas que estoy muy puesto en este asunto.

Pero lo que hace Excel tiene su lógica, para evitar ediciones en un archivo que ya está abierto "de forma exclusiva", por el mismo Excel o por otra aplicacion. Pero, esto lo hace Excel... mas no todas las aplicaciones lo hacen.

Me parece que es al contrario: lo normal es abrir archivos no de forma exclusiva, sino leer su contenido y ponerlo a disposición del usuario, pero, dejar el archivo donde estaba y como estaba. Pero, creo que me estoy yendo por las ramas.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #8  
Antiguo 04-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Bueno, yo también me he enfrentado a ese problema y la solución que le di es lo que dice dec, abrir, ademas, de forma exclusiva, guardar el manejador del fichero para luego "liberarlo" al cerrar. De esa manera detectaba que el fichero no podía ser "tocado".

Saludos.
Responder Con Cita
  #9  
Antiguo 05-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
Cita:
Empezado por dec Ver Mensaje
Hola,

No sabía de esto último que dices Felipe. Aunque, probablemente, Excel abra el archivo "de forma exclusiva", y así luego puede averiguar si el archivo está abierto de esa forma: aunque sea por la propia aplicación, de modo que lo abra como "sólo lectura". Lo cierto es que tampoco te creas que estoy muy puesto en este asunto.

Pero lo que hace Excel tiene su lógica, para evitar ediciones en un archivo que ya está abierto "de forma exclusiva", por el mismo Excel o por otra aplicacion. Pero, esto lo hace Excel... mas no todas las aplicaciones lo hacen.

Me parece que es al contrario: lo normal es abrir archivos no de forma exclusiva, sino leer su contenido y ponerlo a disposición del usuario, pero, dejar el archivo donde estaba y como estaba. Pero, creo que me estoy yendo por las ramas.
Hola Dec, estoy de acuerdo contigo en lo de leer el contenido del archivo y no tenerlo exclusivamente... pero, aunque no manejo el asunto creo que en este caso no aplicaría, según el cuestionamiento del hilo, es la manera de evitar mover un documento cuando se trabaja en el; yo lo veo como una cuestión de seguridad para los datos... si guardaras algo no te dejaría. La pregunta es, ¿hasta que punto Windows permite mover un archivo, estando en uso? ... no se que piensan de esto.

Saludos
Responder Con Cita
  #10  
Antiguo 05-12-2008
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

El asunto está en determinar qué entendemos por un archivo "en uso". Si yo desde Delphi abro para leerlo un archivo de texto y lo cargo en un "TMemo", ese archivo realmente no está "en uso". Simplemente lo abrí, lo leí y ya está. Para que pueda considerarse que un archivo está usándose, hasta donde yo llego, una aplicación ha de abrir el archivo en cuestión "en modo exclusivo", tal como apunta también el compañero Escafandra. En este caso Windows no dejaría mover el archivo abierto "en exclusiva" por una aplicación. Al menos hasta donde yo llego.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #11  
Antiguo 05-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
Claro Dec... de acá en adelante depende es del modo en como "usen" esos archivos los otros programas...
Responder Con Cita
  #12  
Antiguo 06-12-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Cita:
Empezado por felipe88 Ver Mensaje
...es la manera de evitar mover un documento cuando se trabaja en el; yo lo veo como una cuestión de seguridad para los datos... si guardaras algo no te dejaría. La pregunta es, ¿hasta que punto Windows permite mover un archivo, estando en uso? ... no se que piensan de esto...
Falso; pongamos un ejemplo practico, wmplayer (Windows Media Player) reproduce una canción; lee de un archivo multimedia y moverlo (en la anterior teoria), ocasionaría fallas inesperadas en el programa... sin embargo el archivo puede ser movido, y no solo eso, puede ser hasta eliminado (lo cual ocurrirá de forma "visible" cuando sea liberado su manejador)

Esto es posible porque se ha utilizado FILE_SHARE_DELETE al momento de abrir el archivo... que sucede? al ser borrado o eliminado el archivo los datos siguen allí intactos lo único que cambia son las entradas de ROOT o de MFT en el sistema de archivos.

Cita:
Empezado por dec Ver Mensaje
...Pero, si la aplicación que abre un archivo (y es lo normal) no lo abre de forma exclusiva, ya digo, puedo estar equivocado, pero, ¿cómo podría averiguarse que el archivo en cuestión está abierto?...
He visto el tema más de un par de veces y creo que es de interés...

El S.O. bloquea por alguna razón lógica un archivo, y es necesario forzar el acceso al mismo por cualquier motivo... para ello la mejor herramienta que puedo nombrar de la telaraña es "Unlocker" de Cedrick Collomb.

Por qué es tan eficaz dicha herramienta? sin ánimos de quitar el encanto y la excelente calidad del trabajo de Collomb, comentaré que dicha herramienta funciona basada en dos APIs (ObReferenceObjectByHandle & ObfDereferenceObject) las cuales a nivel de núcleo (S.O.) desbloquean los archivos a voluntad y de la mejor forma posible.

Lo anteriormente dicho es solo con fines informativos pues no tenemos el permiso del autor para crear una librería basada en su trabajo, pero si podemos apoyarnos en otras APIs que nos facilitaran el trabajo; adjunto un ejemplo que dará la idea de lo que digo:

Código Delphi [-]
program WhoUses; // by cHackAll

uses Windows;

function NtQuerySystemInformation(SystemInformationClass: Cardinal; SystemInformation: Pointer; SystemInformationLength: Cardinal; ReturnLength: PCardinal): Cardinal; stdcall external 'ntdll';
function NtQueryInformationFile(FileHandle: Cardinal; IoStatusBlock: PInt64; FileInformation: Pointer; FileInformationLength, FileInformationClass: Cardinal): Cardinal; stdcall external 'ntdll';
function NtQueryObject(ObjectHandle, ObjectInformationClass: Cardinal; ObjectInformation: Pointer; ObjectInformationLength: Cardinal; ReturnLength: PCardinal): Cardinal; stdcall external 'ntdll';
function NtQueryInformationProcess(ProcessHandle, ProcessInformationClass: Cardinal; ProcessInformation: Pointer; ProcessInformationLength: Cardinal; ReturnLength: PCardinal): Cardinal; stdcall external 'ntdll';
function GetProcessImageFileNameW(hProcess: Cardinal; lpImageFileName: PWideChar; nSize: Cardinal): Cardinal; stdcall external 'psapi';
function memcmp(lpBuffer1, lpBuffer2: PWideChar; Size: Cardinal): Integer; cdecl external 'ntdll';
function GetConsoleWindow: Cardinal; stdcall external 'kernel32';

var
 Buffer: array [0..1023] of WideChar;

function Thread(Handle: Cardinal): Cardinal; stdcall;
var IoStatusBlock: int64;
begin
 Result := NtQueryInformationFile(Handle, @IoStatusBlock, @Buffer, SizeOf(Buffer), 9);
end;

type
 TSystemHandleInformation = packed record
  uCount: Cardinal;
  Handles: array [0..0] of packed record
   uIdProcess: Cardinal;
   ObjectType,
   Flags: Byte;
   Handle: Word;
   pObject: Pointer;
   GrantedAccess: ACCESS_MASK;
  end;
 end;

var
 hToken, Size, Index, hProcess, hObject, hThread, hOutput: Cardinal;
 Info: ^TSystemHandleInformation;
 Drives: array ['A'..'Z'] of record
  cbSize: Cardinal;
  Volume: array [0..63] of WideChar;
 end;
 Drive: array [0..7] of Char = '@'#0':';

begin
 if OpenProcessToken($FFFFFFFF, TOKEN_ADJUST_PRIVILEGES, hToken) then
  AdjustTokenPrivileges(hToken, False, PTokenPrivileges(PChar(#1#0#0#0#20#0#0#0#0#0#0#0#2#0#0#0))^, 16, nil, PDWORD(0)^);

 repeat Inc(Drive[0]);
  with Drives[Drive[0]] do
   cbSize := QueryDosDeviceW(@Drive, @Volume, SizeOf(Volume)) * 2 - 4;
 until Drive[0] = 'Z';
 Drive[4] := '\';

 Size := SizeOf(TSystemHandleInformation);
 Info := Ptr(LocalAlloc(0, Size));
 NTQuerySystemInformation(16, Info, Size, @Size);
 LocalFree(Cardinal(Info));
 Info := Ptr(LocalAlloc(0, Size));
 NTQuerySystemInformation(16, Info, Size, nil);

 hOutput := 0;
 for Index := 0 to Info.uCount - 1 do
  with Info.Handles[Index] do
   begin
    hProcess := OpenProcess(PROCESS_DUP_HANDLE or PROCESS_QUERY_INFORMATION, True, Info.Handles[Index].uIdProcess);
    if hProcess = 0 then Continue;

    if DuplicateHandle(hProcess, Handle, $FFFFFFFF, @hObject, 0, True, 0) and
       (NtQueryObject(hObject, 2, @Buffer, SizeOf(Buffer), nil) = 0) and
       (lstrcmpW(@Buffer[48], 'File') = 0) then
     begin
      hThread := CreateThread(nil, 0, @Thread, Ptr(hObject), 0, PDWORD(0)^);
      if WaitForSingleObject(hThread, 666) = 0 then
       if (NtQueryObject(hObject, 1, @Buffer, SizeOf(Buffer), nil) = 0) then
        begin
         Drive[0] := 'A';
         while Drive[0] <= 'Z' do
          with Drives[Drive[0]] do
           if (cbSize <> 0) and (memcmp(@Buffer[4], @Volume, cbSize) = 0) then
            Break
           else
            Inc(Drive[0]);
         if Drive[0] > 'Z' then Continue;

         if hOutput = 0 then
          begin
           AllocConsole;
           hOutput := GetStdHandle(STD_OUTPUT_HANDLE);
           SetConsoleScreenBufferSize(hOutput, PCoord(PChar(#120#0#50#0))^);
           SetWindowPos(GetConsoleWindow, 0, 0, 0, $FFFF, 666, SWP_NOZORDER or SWP_NOMOVE);
          end;

         WriteLn(string(PWideChar(@Drive)) + string(PWideChar(@Buffer[5 + (Drives[Drive[0]].cbSize div 2)])));

         if GetProcessImageFileNameW(hProcess, @Buffer, SizeOf(Buffer)) <> 0 then
          begin
           Drive[0] := 'A';
           while Drive[0] <= 'Z' do
            with Drives[Drive[0]] do
             if (cbSize <> 0) and (memcmp(@Buffer, @Volume, cbSize) = 0) then
              Break
             else
              Inc(Drive[0]);
           if Drive[0] <= 'Z' then
            WriteLn(string(PWideChar(@Drive)) + string(PWideChar(@Buffer[Drives[Drive[0]].cbSize div 2 + 1])));
          end;
         WriteLn;
        end
       else
      else
       begin
        TerminateThread(hThread, 0);
        CloseHandle(hThread);
       end;
     end;
    CloseHandle(hProcess);
   end;

 LocalFree(Cardinal(Info));

 if hOutput <> 0 then
  ReadLn;
end.

La anterior aplicación de consola muestra todos los archivos abiertos y los programas que han abierto a dichos archivos y puede adaptarse para otros fines .

Es claro que no tiene el “poder” de Unlocker, pero es un precedente para aplicaciones a nivel de usuario que requieran de dichas funcionalidades.

Saludos
__________________
RTFM > STFW > Foro > Truco > Post > cHackAll > KeBugCheckEx
Responder Con Cita
  #13  
Antiguo 06-12-2008
Avatar de felipe88
[felipe88] felipe88 is offline
Miembro Premium
 
Registrado: may 2007
Ubicación: Mi Valle del Cauca... Colombia!!!
Posts: 1.120
Poder: 18
felipe88 Va por buen camino
Cita:
Empezado por cHackAll Ver Mensaje
Falso; pongamos un ejemplo practico, wmplayer (Windows Media Player) reproduce una canción; lee de un archivo multimedia y moverlo (en la anterior teoria), ocasionaría fallas inesperadas en el programa... sin embargo el archivo puede ser movido, y no solo eso, puede ser hasta eliminado (lo cual ocurrirá de forma "visible" cuando sea liberado su manejador)
Que es falso ... ¿que no puedas guardar en un archivo cuando ya no existe, o que windows administre estas acciones?...
Responder Con Cita
  #14  
Antiguo 30-12-2008
nanozaja nanozaja is offline
Miembro
 
Registrado: ene 2007
Posts: 16
Poder: 0
nanozaja Va por buen camino
perdon q me meta... pero el wmp no guarda el archivo en la biblioteca sino lo q referencia es el path donde se aloja el archivo y lo usa cuando esta reproduciendo... de hecho, intenta borrar o mover un archivo mientras lo esta reproduciendo y no te va a dejar.... aunque si los archivos estan cargados en tu lista, vos podes borrarlos o moverlos, solo perdes la referencia en tu wmp o cualquier otro reproductor, puesto q el archivo todavia no fue tocado... no aporto mas porque esta claro lo q dice dec, el archivo puede ser leido sin mantenerlo abierto en forma exclusiva, aunque diferente es q mantengas la aplicacion abierta con el uso del archivo... hay q separar esos 2 ptos, pero de todos modos, no es posible saber si un archivo esta siendo abierto, salvo q intentes modificarle algo y salte el bendito cartel alertando q es una operacion invalida(como borrar o mover un archivo mientras esta siendo reproducido en el wmp ). saludosssssss
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
ClientdataSet como saber si esta abierto? Coco_jac Varios 4 13-04-2012 19:36:43
Cómo saber si un fichero esta marcado de sólo lectura ? David Varios 2 13-08-2008 16:20:19
¿Está abierto un fichero? Wellnic API de Windows 1 14-06-2008 14:07:14
Saber si un puerto esta abierto Besto Varios 12 10-10-2007 16:30:00
Saber si esta abierto un documento Word Investment Servers 2 13-05-2004 12:02:26


La franja horaria es GMT +2. Ahora son las 17:37:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi