Newsgroup: it.comp.lang.delphi
Titolo: File in uso da altre applicazioni

Ho dei problemi ad individuare se un file è in uso da un'altra applicazione.
Fino ad oggi utilizzavo questa funzione, che però non funziona se, ad
esempio, il file è aperto con Excel (sto provando con Excel 2002)
function IsFileInUse(fName : string) : boolean;
var
  HFileRes : HFILE;
  F: file;
  buf: array[1..1] of Char;
  sTmpFile: string;
begin
  Result := false;
  if fName = '' then Exit;
  if not FileExists(fName) then exit;
  HFileRes :=
    CreateFile(pchar(fName),
               GENERIC_READ or GENERIC_WRITE,
               0, nil, OPEN_EXISTING,
               FILE_ATTRIBUTE_NORMAL,
               0) ;
  Result := (HFileRes = INVALID_HANDLE_VALUE) ;
  if not Result then
    CloseHandle(HFileRes)
  else begin
    //the file seems to be in use...is it really?
    {$I-}
    AssignFile(F, fName);
    FileMode := fmOpenReadWrite;  
    Reset(F, 1);
    if FileSize(F) > 0 then begin
      BlockRead(F, buf, SizeOf(buf));
      Result := IOResult <> 0;  //arriva qua e IOResult è 0
    end else begin
      sTmpFile := GetTempName('zzz', True);
      Result := not CopyFile(PChar(fName), PChar(sTmpFile), False);
      DeleteFile(sTmpFile);
    end;
    CloseFile(F);
    {$I+}
  end;
end;
Im pratica la mia funzione mi dice che non è in uso, riesco ad aprire il
file con un editor di testo (UltraEdit) ma poi il componente che deve
accedere a questo file mi restituisce un errore perchè il file è in uso.
Avete qualche suggerimento?
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Se un po' di sincerità è pericolosa, molta sincerità è addirittura fatale
(Oscar Wilde)

Prova questa:
Function FileInUso(Const FileName : String) : Boolean;
Var
   F      : File;
   Errore : Integer;
Begin
   Result := False;
   If Not FileExists(FileName) Then Exit;
   AssignFile(F, FileName);
   Try
     Reset(F);
     CloseFile(F);
     Errore := 0;
   Except
     Errore := GetLastError;
   End;
   // ----------------------------------------------------
   // Se il file è bloccato da un'altro processo aspetta
   // negli altri casi esce (l'errore verrà visualizzato
   // come RunTimeError)
   // ----------------------------------------------------
   Result := (Errore = ERROR_SHARING_VIOLATION) Or (Errore = 
ERROR_LOCK_VIOLATION)
End;
Ciao,
David

 
Negativo, ottengo lo stesso risultato, e cioč che il file non č in uso.
Nella mia procedura la CreateFile mi dice effettivamente che il file č in
uso ma ho dovuto aggiungere l'altro controllo perchč a volte mi restituiva
che il file era in uso anche se poi non era vero, per cui ho pensato "Se
riesco ad aprire il file e leggerne il contenuto dovrei essere a posto..."
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
La natura non fa nulla di inutile (Aristotele)

Prova cosi'
nella procedura che ti ho inviato visualizza il contenuto della 
variabile Errore (subito dopo la chiamata a GetLastError) e, se è zero 
sono cavoli in quanto il file dovrebbe essere ok, se è diverso guarda 
che errore ti ritorna (la lista degli errori la trovi in Windows.pas - 
nota il numero nella unit è in esadecimale).
Dopo che hai capito il codice di errore vai nell'help delle Api di 
Windows e guarda da cosa deriva

> Avete qualche suggerimento?
Si, ne ho 2!
1. Fare un debug della tua funzione, per scoprire xchè ti da errore, e 
   dove.
2. Cercare un altra funzione su 
delphi.about.com
Diego
--- posted by geoForum on 
http://www.delphiedintorni.it

 essere a posto..."
Prova la soluzione di microges che mi sembra pulita.
Se non va potresti provare a rinominare il file con RenameFile se il file 
viene rinominato allora non è in uso se non lo rinomina vuol dire di si.
Questo è quello che io chiamo "soluzione a pezza" ma dovrebbe andare.


Mi sono ricordato che tra i miei tips ho questa funzione, provala e fammi 
sapere, a ma funziona sempre.
Diego
function IsFileInUse(fName : string) : Boolean;
var
    HFileRes : HFILE;
begin
  Result := False;
  if not FileExists(fName) then exit;
  HFileRes := CreateFile( PChar(fName),
                          GENERIC_READ or GENERIC_WRITE,
                          0, nil, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0 );
  Result := (HFileRes = INVALID_HANDLE_VALUE) ;
  if not Result
  then CloseHandle( HFileRes );
end;


 2. Cercare un altra funzione su 
delphi.about.com
Il suggerimento di leggere il contenuto del file se la CreateFile ha esito
positivo l'ho letto proprio facendo un pò di ricerche. Ora sto provando con
la TFileStream...
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Finita questa mostra, di luce elettrica non sentiremo più parlare (E.Wilson)

 sono cavoli in quanto il file dovrebbe essere ok, se è diverso guarda 
Esatto, il risultato è 0 (quindi file non in uso). 
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Spesso tutti sono convinti che una cosa sia impossibile, finché arriva uno
sprovveduto che non lo sa e la realizza... (Albert Einstein)

 Questo Ã¨ quello che io chiamo "soluzione a pezza" ma dovrebbe andare.
Una soluzione un pò rude, ma al limite proverò anche questa :)
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Pensate da uomini saggi, ma parlate come la gente comune (Aristotele)

 function IsFileInUse(fName : string) : Boolean;
LOL!
Guarda i nomi delle variabili...è la stessa funzione da cui sono partito io
e che poi ho dovuto modificare perchè in alcuni casi la CreateFile indica
che il file è in uso mentre invece è possibile accedere al file (leggi...il
componente che sto utilizzando non ha problemi con quel file)
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Donne?...non mi fido di una cosa che sanguina per 5 giorni di fila al mese e
non muore

 Avete qualche suggerimento?
Per la cronaca, dopo aver sentito il produttore del componente, è stato
sufficiente cambiare i parametri della CreateFile in:
CreateFile(pchar(fName),
           GENERIC_READ,
           FILE_SHARE_READ,
           nil,
           OPEN_EXISTING,
           FILE_ATTRIBUTE_NORMAL,
           0) ;
In questo modo abbiamo verificato di utilizzare lo stesso metodo per
accedere ai file.
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
L’ottimista pensa che questo sia il migliore dei mondi possibili. Il
pessimista sa che è vero. (R.Oppenheimer)