Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Dateien in Benutzung ermitteln. (https://www.delphipraxis.net/191902-dateien-benutzung-ermitteln.html)

MartinK 1. Mär 2017 21:31

Dateien in Benutzung ermitteln.
 
Um eine BackupFunktion für meine Programmdaten zu erstellen,
- zippe ich den kpl. Inhalt meines AppDat Ordners in eine datei (darin speicher ich ebenfalls die Daten)
- überspiele/ersetze im BackupFall den aktuellen AppData Ordner mit den im Zip-File gespeicherten Backup.


soweit so gut. Ich habe allerdings das Problem dass mir das aus sicherheitsgründen notwendige "Umbenennen" des AppData Ordners nicht gelingt (ich will diesen nicht gleich löschen sondern erst umbennnen um ihn notfalls wieder zurückerhalten zu können).
Vermutlich ist mein Problem das ich in irgendeiner meiner vielen Routinen eine Datei nicht wieder geschlossen habe (es sind sehr viele.....) und deswegen das rename des ganzen Ordners fehlschlägt.

Im Endeffekt wäre mir damit geholfen wenn ich herausfinden könnte "welche Dateien dort aktuell noch geöffnet sind".
Dann könnte ich die dafür verantw. bugs im Code beseitigen und dann sollte das laufen.

Nach etwas Forensuche wäre hierfür die JEDi VCL eine option. Mit dieser habe ich allerdings mit meinem XE7 das problem dass dies nocht nicht unterstützt wird.
Help Please

vG Martin

HolgerX 2. Mär 2017 04:25

AW: Dateien in Benutzung ermitteln.
 
Hmm..

wenn mit ein bisschen Google hättest Du sowas gefunden

Delphi-Quellcode:
function FileInAccess(AFileName : Widestring):boolean;
var
  HFileRes: HFILE;
begin
  HFileRes := CreateFileW(PWideChar(AFileName),
                         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;

Dies entspricht auch dem Microsoft-Vorschlag (leider Link nicht zur Hand..).

Es kann nur zu Problemen kommen, wenn Du das mit ReadDirectoryChangesW/GetQueuedCompletionStatus einsetzt.
Hier ist es bei einem Tool von uns (Überwachung von Verzeichnissen und Einlesen neu erstellter Dateien) zum Problem gekommen, das wir das CreateFile bekommen haben, dann geprüft haben ob das File 'Frei' ist.
Jedoch sind wir teilweise mit der obrigen Prüfung so schnell gewesen, dass wir dem anderen Programm, welches die Datei schreiben sollte zwischen dessem CreateFile und WriteFile dazwischen gegrätscht sind.

Denn Windows macht intern erste ein CreateFile -> CloseFile -> ReopenFile (mit Prozessexplorer beobachtet) und wir sind dann zwischen CloseFile und Reopen dazwischen gegangen und haben mit der Prüfung das File bereits geöffnet ;)

Solange Du aber nur deine eigenen Dateien Überprüfst, sollte es gehen...

jaenicke 2. Mär 2017 08:02

AW: Dateien in Benutzung ermitteln.
 
Entscheidend sind hier Process Monitor von Microsoft und auch der schon genannte Process Explorer von dort.

Mit den beiden Tools kannst du sehen welche Handles auf Dateien noch offen sind (Process Explorer, im Menü "Suche Handles") und ggf. auch sehen wann wie darauf zugegriffen wird (Process Monitor).

himitsu 2. Mär 2017 08:05

AW: Dateien in Benutzung ermitteln.
 
Auch die Suchfunktion in der DP liefert garantiert mehrere Funde.

Wer nicht mit PChar und WinAPI hantieren will, kann auch die passenden Wrapper verwenden.
Delphi-Quellcode:
function CheckFileAccess(const FileName: string): Boolean;
var
  H: THandle;
begin
  H := FileOpen(FileName, fmOpenRead or fmShareDenyNone);
  FileClose(H);
  Result := H <> INVALID_HANDLE_VALUE;
end;
CloseHandle/FileClose prüfen intern auf INVALID_HANDLE_VALUE, womit man das nicht selber zu machen braucht.


Will man aber wissen wer diese Dateien geöffnet hat, dann es gibt im Windows eine neuere API, wo Programme quasi zur Datei ihren Namen hinterlegen können.
Wenn sie es nicht machen, dann gibt es keinen offiziellen Weg, um da dran zu kommen. (Inoffizielle APIs und z.B. die Programme von SysInternals mal ausgenommen)

Uwe Raabe 2. Mär 2017 09:13

AW: Dateien in Benutzung ermitteln.
 
Zitat:

Zitat von MartinK (Beitrag 1362986)
das ich in irgendeiner meiner vielen Routinen eine Datei nicht wieder geschlossen habe

Es geht offenbar nicht darum, daß andere Prozesse die Datei offen halten, sondern das Programm selbst.

jobo 2. Mär 2017 15:39

AW: Dateien in Benutzung ermitteln.
 
Kann man nicht einfach die geöffneten Dateien unter Computerverwaltung durchsehen?
Oder wird da nichts angezeigt?

himitsu 2. Mär 2017 15:55

AW: Dateien in Benutzung ermitteln.
 
Die Computerverwaltung zeigt Dateien an, welche über eine Netzwerkfreigabe geöffnet sind.

Luckie 2. Mär 2017 19:27

AW: Dateien in Benutzung ermitteln.
 
Wenn es nur darum geht den Fehler im eigenen Code zu finden, sollte es der Prozess Explorer und Konsorten doch tun.

Klingt aber als wenn du unsauber progranmiert hättest. Guck doch mal den Code durch: Nicht freigegeben FileStreams, nicht geschlossene Dateihandle usw...

MartinK 2. Mär 2017 22:09

AW: Dateien in Benutzung ermitteln.
 
Danke für die zahlreichen Tipps
ich denke ich werde mich zunächst mit den beiden MS Tools versuchen und anschl. Rückmeldung geben woran's lag und wie ich es rausgefunden habe.

vG Martin

MartinK 4. Apr 2017 12:45

AW: Dateien in Benutzung ermitteln.
 
Zwischenstand:
- Es handelt sich doch um nicht um eine "geöffnete Datei" ansich, sondern um einen "(Unter)Ordner" innerhalb Appdata/Roaming den meine Applikation scheinbar irgendwie blockiert.
Dieser Ordner kann nicht gelöscht/Renamed werden , was ich aber tun müsste (für eine Backup-Funktionalität).

- Ich bin mir ziemlich sicher dass ich keine "Bugs im Code an sich habe". Wie sollte ich auch einen Ordner "offen halten". Bei Ordnern gibt es ja kein "CloseFile", "free" etc.
Der Process-Explorer und Process Monitor von MS werden mir deswegen vermutlich auch nur wenig bei der Suche helfen :(

- Was ich jetzt noch getestet habe: Ich habe im Programm verwendete Komponenten die eine "Directory-Eigenschaft" die dies evtl. verursachen könnten, -> diese habe ich per Sourcecode bewusst auf einen anderen Ordner umgestellt.
und zwar bei allen TOpenDialog(InitialDir), TSaveDialog (InitialDir), TDirectoryListbox (Directory)
leider war es das auch (noch) nicht

Habt ihr noch Ideen was ich noch prüfen könnte ? Gibt es überhaupt noch weitere Komponenten die eine Directory Eigenschaft habe die mir jetzt nicht aufgefallen sind?

vG Martin

himitsu 4. Apr 2017 13:35

AW: Dateien in Benutzung ermitteln.
 
"Offen" bedeutet, dass irgendwo ein "Handle" auf diesem Dateisystemobjekt (Datei oder Verzeichnis) liegt, also eine "geöffente" Verbindung.
Und ja, das gibt es auch zu Verzeichnissen, denn für das Dateisystem (z.B. FAT und NTFS) sind Verzeichnisse auch nur "Dateien".
z.B. das aktive Arbeitsverzeichnis oder eine aktive Dateisuche ala (FindFirst/FindFirstFile).

Versuch mal
Delphi-Quellcode:
SetCurrentDirectory(PChar(ExtractFileDir(ParamStr(0))));
.

Diese Dialoge ändern das aktuelle Arbeitsverzeichnis.
PS: Das ist übrigens auch einer der unzähligen Gründe, warum man niemals mit relativen Pfaden arbeiten sollte.

p80286 4. Apr 2017 14:01

AW: Dateien in Benutzung ermitteln.
 
Zitat:

Zitat von MartinK (Beitrag 1366391)
Zwischenstand:
- Es handelt sich doch um nicht um eine "geöffnete Datei" ansich, sondern um einen "(Unter)Ordner" innerhalb Appdata/Roaming den meine Applikation scheinbar irgendwie blockiert.
Dieser Ordner kann nicht gelöscht/Renamed werden , was ich aber tun müsste (für eine Backup-Funktionalität).

da ich selbst nicht so tief in den Untiefen von Windows bewandert bin, es gibt Situationen in denen sich (unter)Ordner gegen Löschung/Umbenennung wehren, obwohl kein offensichtlicher Grund hierfür vorliegt. Typisch ist dann eine Fehlermeldung ohne jeden Bezug zur scheinbaren Realität mit den Optionen Wiederholen,Überspringen,Abbrechen.
Versuchst Du die gleichen Aktivitäten mit Hilfe einer Batch-Datei zu erledigen, klappt es in den meisten Fällen. Will sagen, u.u ist es API-Abhängig wie Dateien/Verzeichnisse reagieren und es könnte sein daß im Hintergrund der eine oder andere Service sich für Deine Datei/Verzeichnis interessiert. Zusätzlich können einzelne Dateien, für die Du nicht die notwendige Berechtigung hast, ganze Datei(gruppen) vor Zugriffen "schützen".

Gruß
K-H

MartinK 4. Apr 2017 15:52

AW: Dateien in Benutzung ermitteln.
 
Zitat:

Zitat von himitsu (Beitrag 1366398)
"Offen" bedeutet, dass irgendwo ein "Handle" auf diesem Dateisystemobjekt (Datei oder Verzeichnis) liegt, also eine "geöffente" Verbindung.
Und ja, das gibt es auch zu Verzeichnissen, denn für das Dateisystem (z.B. FAT und NTFS) sind Verzeichnisse auch nur "Dateien".
z.B. das aktive Arbeitsverzeichnis oder eine aktive Dateisuche ala (FindFirst/FindFirstFile).

Ich glaube genau das war der entscheidende Hinweis auf der Suche nach der Nadel im Heuhaufen!
Habe nochmal alle FindNext in meinem SourceCode Aufrufe separat überprüft und dabei einen aus dem WWW kopierten Sourcecode einer Funktion als vermutlich Übeltäter entlarvt.
Dort wurde FindClose vergessen

sieht so aus als bekäme ich es endlich in den Griff !

:) :)

M

nahpets 4. Apr 2017 22:11

AW: Dateien in Benutzung ermitteln.
 
Was mir in dem Zusammenhang noch einfällt:

Wenn man z. B. mit einem Dateiöffnendialog ... was öffnet / auswählt, so wechseln diese Dialoge ganz gerne mal das Verzeichnis, womit das Arbeitsverzeichnis des Programmes nun das Verzeichnis wird, aus dem man was auswählte.

Ein Verzeichnis, das von irgendeiner Applikation als Arbeitsverzeichnis genutzt wird, kann man in der Regel weder umbenennen, noch löschen.

Bei vielen Dialogen kann man unter Optionen ofNoChangeDir auf True setzen. Damit könnte man dann eventuell eine mögliche Ursache des Problems beseitigen.

Hannah French 5. Apr 2017 03:42

AW: Dateien in Benutzung ermitteln.
 
Thanks for the numerous tips :-D
json editor

MartinK 5. Apr 2017 03:46

AW: Dateien in Benutzung ermitteln.
 
Zitat:

Zitat von Hannah French (Beitrag 1366449)
Thanks for the numerous tips :-D [/URL]

+1

DANKE
Martin


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:37 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