Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Schreib-/Leserechte auf CSIDL_COMMON_APPDATA (https://www.delphipraxis.net/104665-schreib-leserechte-auf-csidl_common_appdata.html)

dominikkv 8. Dez 2007 15:08


Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
Hi

habe ich Lese/Schreibrechte auf dem Common Appdata Ordner (CSIDL_COMMON_APPDATA)?
Der ist ja eigendlich dazu da um von jedem Benutzer zugreifbar zu sein... nur ich bekomme Probleme bei folgendem Code:
Delphi-Quellcode:
if FileExists(Source) then
  try
    assignFile(f, Source);
    reset(f);
    read(f, a); // Nur lesen!
  finally
    closeFile(f);
  end;
Wenn die Stelle ausgeführt wird gibts keine Probleme, erst wenn das Programm beendet wird (und dabei wird diese Stelle nicht ausgeführt) gibt es eine Fehlermeldung bei closeFile mit dem Fehler EInOutError: File access denied.

Das finde ich komisch, da
1) ich ja nur lese
2) ich eigendlich Schreibrechte auf CSIDL_COMMON_APPDATA habe... ich kann zumindest Bilder speichern!

Was sagt ihr dazu?

mfg.Dominik

mirage228 8. Dez 2007 16:16

Re: Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
Ja wenn beim Beenden die Stelle gar nicht augeführt wird, wo tritt dann der Fehler genau auf? Wird vielleicht CloseFile() für ein ungültiges "f" aufgerufen? Was sagt der CallStack?

Weil bei dem Ordner hat man auf jeden Fall normalerweise Lese und Schreibrechte!

mfG
mirage228

dominikkv 8. Dez 2007 16:51

Re: Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
Zitat:

Zitat von mirage228
Ja wenn beim Beenden die Stelle gar nicht augeführt wird, wo tritt dann der Fehler genau auf?

Das frage ich mich ja auch...
Auf jedenfall kommt der Fehler nach Application.Terminate, aber vor MainForm.FormDestroy.

Zitat:

Zitat von mirage228
Wird vielleicht CloseFile() für ein ungültiges "f" aufgerufen?

Was meinst du mit ungültig? F ist so deklariert:
Delphi-Quellcode:
type
  TString8 = String[8];
  TString100 = String[100];

  TVersion = record
    Name: TString100;
    Version: TString8;
    Datum: TDateTime;
  end;

// ...

function CheckUpdates: Boolean;
var F: File of TVersion;
    A: TVersion;
begin
  result := False;
  if FileExists(VerFile) then
    try
      assignFile(f, VerFile);
      reset(f);
      read(f, A);
    finally
      closeFile(f);
    end else
      A.Version := '0.0.0.0';
// usw...
Nach den CloseFile wird die Prozedure abgebrochen!, allerdings kommt keine Fehlermeldung... die kommt dann bei Programmende.

Zitat:

Zitat von mirage228
Was sagt der CallStack?

Den Delphi-Debugger kann ich nicht benutzen da ich Delphi mit Adminrechten ausführe (und da kommt der Fehler nicht!), aber der CallStack von madExcept sagt dass ich bei genau dieser procedur bin (sogar mit Linienangabe, eben auf closeFile(f);)
Code:
Main ($cfc):
005e8336 +0ba MyProg.exe    uStuff   152  +8 CheckUpdates
005e1bcc +4ec MyProg.exe    uOptionen 415 +79 LoadProgFromFile
005e88fc +1cc MyProg.exe    uStuff   238 +42 AfterCreate
005f9e07 +0ff MyProg.exe    MyProg    48 +15 initialization
762b19ef +00c kernel32.dll                  BaseThreadInitThunk
Zitat:

Zitat von mirage228
Weil bei dem Ordner hat man auf jeden Fall normalerweise Lese und Schreibrechte!

Genau, eine andere Datei die ganau im gleichen Ordner liegt wird auch bei Programmstart mit AssignFile etc gelesen, ohne Fehler!

Achja: die Fehlermeldung heißt jetzt EInOutError: I/O error 103.

Danke schonmal für deine Hilfe :cheers:

Achim Kalwa 8. Dez 2007 17:28

Re: Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
Obwohl Du später nur "read" verwendest, wird die Datei trotzdem immer zum Lesen und Schreiben geöffnet!

Setze mal vor dem Öffnen den Filemode auf fmOpenRead:
Delphi-Quellcode:
if FileExists(Source) then
  try
    FileMode := fmOpenRead; // aus SysUtils
    assignFile(f, Source);
    reset(f);
    read(f, a); // Nur lesen!
  finally
    closeFile(f);
  end;
Der Standard-Wert für FileMode ist nämlich fmOpenReadWrite (=2)

Aber Achtung:
Wenn Du FileMode änderst, verwenden alle nachfolgenden Reset()-Aufrufe den neuen Filemode. Außerdem ist FileMode nicht Thread-sicher.

Du kannst diese Probleme umgehen, wenn Du statt der "veralteten" Aufrufe AssignFile(), Reset(), Read() das Streaming-System von Delphi verwendest:
Delphi-Quellcode:
if FileExists(VerFile) then
begin
  FS := TFileStream.Create(VerFile, fmOpenRead);
  try
    FS.ReadBuffer(aVersion, SizeOf(aVersion));
    // mach was mit dem gelesenen Datensatz
  finally
    FS.Free;
  end;
end
else
  ...
HTH
KalwaDOS

himitsu 8. Dez 2007 17:38

Re: Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
kann es sein daß madExcept wegen des Try-Finally auf CloseFile zeigt, obwohl der Fehler vielleicht vorher auftritt?

falls ja, dann kommentiere Try-Finally-End mal aus und schau nochmal mit madExcept nach wo jetzt der Fehler ist :gruebel:

DP-Maintenance 8. Dez 2007 17:58

DP-Maintenance
 
Dieses Thema wurde von "Phoenix" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Es geht offensichtlich um Delphi.

dominikkv 8. Dez 2007 18:10

Re: Schreib-/Leserechte auf CSIDL_COMMON_APPDATA
 
pah...ich glaube ich weiß warum...
Ich hab grad gelesen dass nur der Besitzer der Datei Vollzugriff hat, "normale" Benutzer können nur Lesen! Da die datei im Setup (und damit als Admin) erstellt wurde habe ich als normaler Benutzer nur-lese-rechte...

Warum ich dann als normal Benutzer nicht lesen konnte ?!?

Egal... ich erteile dem Odner bei der Installation einfach schreib-rechte und dann gehts :thumb:

An die 2 die gerade geantwortet haben:
Das mit dem try-finally-block hat sich ja jetzt geklärt, und das mit den Streams... ist ne Alternative, werde ich mir auf jedenfall mal anschauen :stupid:

Danke an euch :cheers:


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