Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Appdata, Roaming, etc. (https://www.delphipraxis.net/203898-appdata-roaming-etc.html)

Redeemer 17. Apr 2020 08:01

AW: Appdata, Roaming, etc.
 
ProgramData ist das %Appdata% von Öffentlich, sprich für Sachen, die in keine der Kategorien in Eigene Dokumente passen.

Und wie ich schon schrieb, die allermeisten Programme haben keine für alle Nutzer relevanten Dinge, die sie da reinschreiben können.

freimatz 17. Apr 2020 08:47

AW: Appdata, Roaming, etc.
 
Danke ist mir inzwischen klar. Bei meinem Programm dürfte es schon Daten geben die für alle Nutzer relvant sind. Du schriebst von Plugins. So was gibt es auch bei mir. Wenn einer ein neues Plugin einbindet oder ein vorhandenes updated, soll es für alle User gelten (so zu 99% der Konsens.) Das käme dann m.E. in %ProgramData%.

Unklar ist mir nach wie vor die Bedeutung von %Public% (und wo es eine offizielle Doku gibt).
Ich vermute, dass in meinem Fall ich mit %AppData% und %ProgramData% auskomme und %Public% nicht benötige.

Dalai 17. Apr 2020 17:20

AW: Appdata, Roaming, etc.
 
Zitat:

Zitat von freimatz (Beitrag 1462305)
Ja, bei mir hat es in %Public% auch Documents, Downloads, Pictures, Videos und so. Aber die Daten meines Programmes passen in keine dieser Kategorien.

Das ist ja in Ordnung. Dann speichere die Daten nicht dort, hab ich ja auch nicht gesagt, dass du das tun solltest ;). Eher im Gegenteil.

Zitat:

Wenn ich mich dazu gesellen soll verstehe ich das. Aber wieso soll ich etwas in %Public% speichern (so habe ich dich zumindest verstanden) wenn es doch auch sonst fast keiner tut.
Da hast du mich missverstanden, oder ich mich unklar ausgedrückt. Primär bezog ich mich auf die Unterverzeichnisse Documents, Downloads usw., die eben vom Nutzer befüllt werden sollen und nicht von Programmen, denn für letztere gibt es bereits ausreichend Ablageorte (wie eben %ProgramData% und %AppData%).

Grüße
Dalai

freimatz 18. Apr 2020 10:46

AW: Appdata, Roaming, etc.
 
Ah, ok, Danke. :)

t2000 18. Apr 2020 11:27

AW: Appdata, Roaming, etc.
 
Hier mal die Pfade, die wir benutzen:

Delphi-Quellcode:
var
  CompanyDataPath   : string;  // Pfad für Programmdateien FEST auf company z.B. C:\ProgramData\CompanyName\
  ProgramDataPath   : string;  // Pfad für Programmdateien z.B. C:\ProgramData\CompanyName\ProgramName\
  AppDataRoamingPath : string;  // Pfad für Programmdateien-Benutzer (Netzwerk) z.B. C:\Users\Benutzer\AppData\Roaming\CompanyName\ProgramName\
  AppDataLocalPath  : string;  // Pfad für Programmdateien-Benutzer (lokaler PC) z.B. C:\Users\Benutzer\AppData\Local\CompanyName\ProgramName\
  DocumentsPath     : string;  // Pfad für Benutzerdateien z.B. C:\Users\Benutzer\Documents\CompanyName\ProgramName\
  TempPath          : string;  // Pfad für Temp-Ordner z.B. C:\Users\Benutzer\AppData\Local\Temp\

const
  // https://docs.microsoft.com/de-de/windows/win32/shell/knownfolderid
  FOLDERID_ProgramData   : TGUID = '{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}';
  FOLDERID_RoamingAppData : TGUID = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_LocalAppData  : TGUID = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_Documents     : TGUID = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
und dazu die Initialisierung

Delphi-Quellcode:
function GetFolderPath( folderId: TGUID): string;
var
  path: LPWSTR;
begin
  if SHGetKnownFolderPath( folderId, KF_FLAG_DEFAULT, 0, path) = S_OK then
  begin
    result := path;
    if copy(result, length(result), 1) <> '\' then
      result := result + '\';
  end else
    result := '';
end;

procedure InitPaths( app: string);
begin
  CompanyDataPath   := GetFolderPath( FOLDERID_ProgramData)   + company + '\';
  ProgramDataPath   := GetFolderPath( FOLDERID_ProgramData)   + company + '\' + app + '\';
  AppDataRoamingPath := GetFolderPath( FOLDERID_RoamingAppData) + company + '\' + app + '\';
  AppDataLocalPath  := GetFolderPath( FOLDERID_LocalAppData)  + company + '\' + app + '\';
  DocumentsPath     := GetFolderPath( FOLDERID_Documents)     + company + '\' + app + '\';
  TempPath          := TPath.GetTempPath;
end;
und noch ein paar Hilfsroutinen

Delphi-Quellcode:
function IsDirectoryWriteable(const Directory: string): Boolean;
var
  FileName: String;
  H: THandle;
begin
  FileName := IncludeTrailingPathDelimiter(Directory) + '_check_write.tmp';
  H := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);
  Result := H <> INVALID_HANDLE_VALUE;
  if Result then
    CloseHandle(H);
end;

function IsFileReadOnly(const Filename: string): boolean;
begin
  if FileExists(Filename) then begin
    result := ((GetFileAttributes( PChar(FileName)) and FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY);
    if not result then
      result := not IsDirectoryWriteable( ExtractFilePath( Filename));
  end else begin
    result := false; // damit keine Compilerwarung kommt
    Exception.Create('File: '+Filename+' does not exists.');
  end;
end;

freimatz 25. Apr 2020 09:21

AW: Appdata, Roaming, etc.
 
Hallo,
Danke. Eigentlich suchte (und fand) ich ja Antworten auf grundlegendere Dinge.

Wie man die Pfade abfragt, da habe ich schon etwas und zwar verwende ich eine Methode, die ich vermutlich mal irgendwo kopiert habe. Diese verwendet u.a. SHGetSpecialFolderLocation und SHGetPathFromIDList.
Du verwendest SHGetKnownFolderPath.
Und heute bin ich noch zufällig auf TPath.GetPublicPath in unit System.IOUtils gestossen. Das verwendet SetLastError und SHGetFolderPath.
Nun frage ich mich was die beste Methode ist.

Was für mich gegen TPath spricht:
1. Ich finde nichts was CSIDL_APPDATA verwendet - ah doch GetHomePath indirekt
2. Schlampige Umsetzung (DRY)
3. Verwendet SHGetFolderPath was deprecated sein soll

So scheint Deine Implementation die bessere zu sein. (Abesehen von der Kleinigkeit warum Du nicht IncludeTrailingPathDelimiter verwendest)

Meinungen?

t2000 25. Apr 2020 09:52

AW: Appdata, Roaming, etc.
 
Zitat:

Zitat von freimatz (Beitrag 1462850)
(Abesehen von der Kleinigkeit warum Du nicht IncludeTrailingPathDelimiter verwendest)

Ja, hatte ich nicht dran gedacht. Ist natürlich besser.

Genau weil andere Routinien decrepated sind, habe ich mich dafür entschieden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:41 Uhr.
Seite 2 von 2     12   

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