Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Datei bereits verwendet? (https://www.delphipraxis.net/81933-datei-bereits-verwendet.html)

user0 5. Dez 2006 16:02


Datei bereits verwendet?
 
Hallo Delphi-programmierer,

wie kann ich herrausfinden, ob eine Datei bereits von einem anderen Programm bzw. Prozess
geöffnet wurde? Z.B. Wenn ich eine xls-Datei lesen will, die bereits mit Excel geöffnet wurde.
In diesem Fall soll das Programm eine Kopie der Datei erstellen.

Danke schonmal für eure Hilfe,

user0

ichbins 5. Dez 2006 16:16

Re: Datei bereits verwendet?
 
Wie wärs einfach mit probieren-geht-über-studieren?

Delphi-Quellcode:
assignfile(f,filename);
filemode:=2; //Modus für Lesen und Schreiben, Standard
try
  reset(f)
except
  closefile(f);
  filemode:=0; //Read-Only-Modus (geht auch, wenn die Datei geöffnet ist)
  reset(f);
  dateikopieren;

  filemode:=2; //filemode auf Standard zurücksetzen
end;

Luckie 5. Dez 2006 16:18

Re: Datei bereits verwendet?
 
Und was ist, wenn die Datei nicht exklusiv geöffnet wurde?

Das geht wohl nur über eine Liste mit Programmen, die ein Handle auf die datei geöffnet haben. Siehe dazu FileMon von Sysinternals. Und das wiederum geht wahrscheinlich nur mit einem Dateisystem-Filter-Treiber.

Reinhard Kern 5. Dez 2006 16:25

Re: Datei bereits verwendet?
 
Zitat:

Zitat von Luckie
Und was ist, wenn die Datei nicht exklusiv geöffnet wurde?

....

Versuch doch, sie selbst exklusiv zu öffnen. Wenn das geht, hat sie sonst niemand offen.

Gruss Reinhard

ichbins 5. Dez 2006 17:50

Re: Datei bereits verwendet?
 
Denk ich auch.

Bevor du dir alle Handles per Treiber (den du schlimmstenfalls noch installieren musst und für den du Admin-Rechte benötigst und etc.) zusammenkratzt und überprüfst, versuch einfach die Datei über try...except selbst zu öffnen und das Problem hat sich.

Das ist (abgesehen vom Programmieraufwand) wohl auch weit weniger CPU- und RAM-Intensiver und meiner Meinung auch nicht "unsauber".

himitsu 8. Dez 2006 17:31

Re: Datei bereits verwendet?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Reinhard Kern
Versuch doch, sie selbst exklusiv zu öffnen. Wenn das geht, hat sie sonst niemand offen.

Ich will ja nichts sagen, da es im meistens stimmt...



aber ...


Na ja, im Anhang sind 3 Programme:

Project3 erstellt 'ne Datei und hällt sie geöffnet - der Inhalt wird ausgelesen und angezeigt.

Project4 öffnet diese Datei mit exclusiven Rechten und schreibt was rein.
(könnt euch ja im QuellCode vergewissern)

Project5 öffnet die Datei mit Sharingrechten, ließt/schreibt den Inhalt und zeigt ihn an.


Das, was Project4 und Project5 machen, nochma im Kurzen...
Delphi-Quellcode:
// Project4
FH := CreateFile(PChar('Project3.dat'), GENERIC_READ or GENERIC_WRITE,
  0 {kein FILE_SHARE_READ und FILE_SHARE_WRITE}, nil, OPEN_ALWAYS, 0, 0);
If FH = INVALID_HANDLE_VALUE Then Raise Exception.Create('Can''t open the file.');

While ... do Begin
  i := Random(MaxInt);
  SetFilePointer(FH, 0, nil, FILE_BEGIN);
  WriteFile(FH, i, 4, W, nil);
  Edit1.Text := IntToStr(i);
End;

CloseHandle(FH);
Wie man sieht ... keine SharingRecht.
Delphi-Quellcode:
// Project5
FH := CreateFile(PChar('Project3.dat'), GENERIC_READ or GENERIC_WRITE,
  FILE_SHARE_READ und FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
If FH = INVALID_HANDLE_VALUE Then Raise Exception.Create('Can''t open the file.');

While ... do Begin
  SetFilePointer(FH, 0, nil, FILE_BEGIN);
  ReadFile(FH, i, 4, W, nil);
  Edit1.Text := IntToStr(i);
End;

CloseHandle(FH);


Aber nun mal zum Grund:
[quote="MSDN - CreateFile"]dwShareMode
[in] Sharing mode of the object (reading, writing, both, or neither).
You cannot request a sharing mode that conflicts with the access mode specified in a previous open request whose handle is still open.
Dieses gilt also nur für "offene" FileHandles ... Project3 jedoch öffnet/erstellt die Datei zwar per
Delphi-Quellcode:
FH := CreateFile(PChar('Project3.dat'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
aber schließt daß FileHandle danach wieder. :zwinker:

Demnach würde "... alle Handles per Treiber zusammenkratzt und überprüfst..." leider auch nicht funktionieren. :tonque:
Selbst über FileMon und den ProcessExplorer bekommen man nichts von einem FileHandle in Project3 mit. :shock: (OK, es gibt ja Keines mehr)



Also, für'n "Normalfall" sollte das Öffnen mit exclusiven Rechten vollkommend ausreichend sein
und der winzige Rest wird wohl ein bissl zu aufwendig werden. :engel:
Ich kenn jedenfalls noch keine andere wirkungsvolle Methode dieses "schnell/einfach" zu prüfen.


  • Project3 und danach Project4 starten = Datei läßt sich exclusiv öffnen
  • Project5 und danach Project4 starten = Datei läßt sich nicht exclusiv öffnen
  • Project4 und danach Project5 starten = Datei läßt sich nicht öffen, da bereits exclusiv geöffnen
  • Project5 mehrmals starten = Datei läßt sich öffnen
    Sollte ja auch Aufgrund der SharingRechte so sein.
  • Project5 und Project3 können natürlich beliebig oft gestartet werden.
    Kein Wunder, denn der Aufruf von CreateFile ist ganz genau gleich und mit SharingRechten

Christian Seehase 8. Dez 2006 21:58

Re: Datei bereits verwendet?
 
Moin Himitsu,

Dein "aber" zu Reinhards Aussage kann ich jetzt nicht nachvollziehen.

Ausgangspunkt war es doch festzustellen, ob die Datei im Zugriff ist.
Kann man sie nicht exklusiv öffnen, ist dass nicht der Fall.

Zitat:

Zitat von himitsu
Project3 erstellt 'ne Datei und hällt sie geöffnet - der Inhalt wird ausgelesen und angezeigt.

Zitat:

Zitat von himitsu
Dieses gilt also nur für "offene" FileHandles ... Project3 jedoch öffnet/erstellt die Datei zwar per

Delphi-Quellcode:
FH := CreateFile(PChar('Project3.dat'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
aber schließt daß FileHandle danach wieder. :zwinker:

Was denn nun? :gruebel:
Hält Projekt3 die Datei nun geöffnet, oder wird das Handle wieder geschlossen?

Im ersten schlägt der Versuch die Datei exklusiv zu öffnen fehl, im zweiten nicht.

himitsu 9. Dez 2006 09:59

Re: Datei bereits verwendet?
 
Also, die Datei bleibt im Zugriff (in Project3 zwar nur lesend, aber schreibend wäre och leicht möglich)
und das obwohl das FileHandle wieder freigegeben wurde.

Also es ist möglich sich einen Schreib-/Lesezugriff zu besorgen und das ohne ein FileHandle wärenddessen zu benötigen.

CreateFile prüft aber nur die SharingRechte in vorhandenen FileHandles zur betreffenden Datei.



Project3 öffnet sich die Datei per CreateFile, leitet den Zugriff etwas um und schließt dann sofort das FileHandle wieder, da für diesen Schreib-/Lesezugriff kein FileHandle nötig ist. ^^

Christian Seehase 9. Dez 2006 12:11

Re: Datei bereits verwendet?
 
Moin Himitsu,

dann sei doch mal so gut, und stell auch den Source von Projekt3 hier rein. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:38 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz