Benutzer mit den meisten Antworten
Zugriff auf den AppData-Ordner

Frage
-
Ich würde gern einige Dateien für mein Programm im AppData-Ordner speichern, wofür ich allerdings dort einen Unterordner anlegen müsste.
Ich habe es folgendermaßen versucht:
Allerdings erstellt das Programm dan im Unterordner bin/Debug der Projeltmappe einen Ordner nit dem Namen "%appdata%" und darin den Ordner "hamitgerkansprojects", was ja nicht korrekt ist, weil ich mit der Verwendung von %appdata% den AppData-Ordner ansprechen wollte.if(!System.IO.Directory.Exists("%appdata%/hamitgerkansprojects")) { System.IO.Directory.CreateDirectory("%appdata%/hamitgerkansprojects"); }
Antworten
-
Hallo Hamit,
> Ich würde gern einige Dateien für mein Programm im AppData-Ordner speichern, wofür ich allerdings dort einen Unterordner anlegen müsste
Die Umgebungsvariable %APPDATA% verweist auf das Verzeichnis, in dem programmspezifische Daten für den aktuellen Roamingbenutzer gespeichert werden (
%LOCALAPPDATA% hingegen auf das lokale Verzeichnis für den aktuellen Benutzer). Auf diese Verzeichnisse verweisen ebenfalls zwei Enumerationselemente: Environment.SpecialForders.ApplicationData bzw. Environment.SpecialForders.LocalApplicationData.
Wenn Du aber Programmdaten für alle Benutzer Deines Programms speichern möchtest (vom Programm gemeinsam genutzte Daten), dann müßtest Du das neue Verzeichnis eher unter %ALLUSERSPROFILE%, d.h. Environment.SpecialForders.CommonApplicationData erstellen.
Da die Umgebungsvariablen in vielen Fällen nicht, oder nicht richtig gesetzt sind, empfiehlt sich eher die Verwendung von Environment.SpecialFolders.
Verwendest Du aber trotzdem Umgebungsvariablen, so mußt Du diese vor der Verwendung expandieren:string expandedPath = Environment.ExpandEnvironmentVariables("%appdata%//hamitgerkansprojects"); System.IO.Directory.CreateDirectory(expandedPath); // wird nur erstellt wenn nicht vorhanden
Generell ist es vorteilhaft wenn man Pfade über System.IO.Path.Combine zusammenfügt, z.B. string myDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData), "SubDirectory").
Vorsicht: Der Name des Verzeichnisses ("hamitgerkansprojects") verstößt logisch gegen einige Grundsätze:
1. Environment.SpecialFolders.ApplicationData ist für benutzerspezifische Daten der Applikation und nicht des Benutzers vorgesehen ("projects" legt nahe, dass es sich hier um Projekte von Hamit handelt). Diese sollten, wenn es sich um Dokumente handelt, am besten unter SpecialFolders.Personal/MyDocuments + Unterverz. abgelegt werden.
2. Die Erwähnung des Benutzernamens (Hamit) im Pfadnamen macht bei der Verwendung von Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) nicht viel Sinn, da hier alle Verzeichnisse benutzerbezogen sind und der Name sowieso schon im Pfad steht.
3. Normalerweise steht unter %appdata% als Verzeichnisname der Name der Anwendung, also z.B. C:\Users\Hamit Gerkan\AppData\Roaming\SuperApp.Das Speichern von Daten unter SpecialFolder.ApplicationData hat noch einen weiteren Haken. Wenn Deine Anwendung für alle Benutzer installiert wird, gibt es zur Installationszeit keinen korrekten Speicherort dafür, d.h. eventuelle Daten die Du vorab nach SpecialFolder.ApplicationData schreiben möchtest, dürfen nicht während der Installation sondern erst beim ersten Start der Anwendung nach ApplicationData geschrieben werden.
Auf die Probleme von ApplicationData bei der Verwendung von ClickOnce-Deployment, gehe ich hier nicht ein.Ach ja, fast hätte ich's vergessen: Du kannst natürlich außer über Umgebungsvariable, SpecialFoders-Enumerationselemente auch noch über Application.CommonAppDataPath, Application.LocalUserAppDataPath bzw. Application.UserAppDataPath auf bekannte Verzeichnisse zugreifen. Diese letzten drei Properties haben den Vorteil, dass sie je nachdem ob die Anwendung über ClickOnce oder normal installiert wurde, autom. auf entspr. Verzeichnisse verzweigen (ClickOnce => AppDomain.CurrentDomain.GetData("DataDirectory"), sonst => strukturierter Pfad z.B. Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData))\Firma\Produkt\Version).
Dazu kommen unter Windows 7 weitere Möglichkeiten hinzu, auf die ich hier ebenfalls nicht eingehe.
Environment.SpecialFolder Enumeration
http://msdn.microsoft.com/de-de/library/system.environment.specialfolder.aspxEnvironment.ExpandEnvironmentVariables-Methode:
http://msdn.microsoft.com/de-de/library/system.environment.expandenvironmentvariables.aspxKNOWNFOLDERID (unter Remarks stehen die Standardpfade):
http://msdn.microsoft.com/en-us/library/dd378457(v=vs.85).aspx
Technical requirements for the Windows 7 Client Software Logo Program
http://www.microsoft.com/download/en/details.aspx?id=3859
Gruß
Marcel
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:33
-
Hallo Hamit,
dazu ist einiges zu sagen. Im Prinzip solltest Du immer erstmal die .NET Methoden für die Pfade benutzen und nicht Dinge wie "%appdata%" obwohl das unter Windows sehr oft funktionieren wird. Ich verzichte mal auf eigene Bemerkungen, da diese Dinge sehr gut in den Artikeln beschrieben sind.
Also erstmal die wichtigsten Möglichkeiten dazu:
Pfad für die Anwendungsdaten eines Benutzers:
[Application.UserAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.userappdatapath.aspxPfad für die Anwendungsdaten eines lokalen Benutzers, der kein Roaming verwendet:
[Application.LocalUserAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.localuserappdatapath.aspxPfad für die Anwendungsdaten, die von allen Benutzern gemeinsam genutzt werden:
[Application.CommonAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.commonappdatapath.aspx
[Environment.SpecialFolder-Enumeration (System)]
http://msdn.microsoft.com/de-de/library/system.environment.specialfolder.aspx
CommonApplicationData:
Das Verzeichnis, das als allgemeines Repository für programmspezifische Daten verwendet
wird, die von allen Benutzern verwendet werden.
LocalApplicationData:
Das Verzeichnis, das als allgemeines Repository für programmspezifische Daten verwendet
wird, die von einem aktuellen Benutzer verwendet werden, der kein Roamingbenutzer ist.Hier detailliertere Möglichkeiten ab Vista und später, mit denen man sehr dedizierte Ordner-Positionen angeben kann:
[KNOWNFOLDERID (Windows)]
http://msdn.microsoft.com/en-us/library/dd378457(VS.85).aspx
[CSIDL (Windows)]
http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx -> CSIDL_APPDATA[ReadMe.txt - Shell known folder sample (CSShellKnownFolders)]
http://code.msdn.microsoft.com/CSShellKnownFolders-94aa920a/sourcecode?fileId=21702&pathId=1556858234
========================================Trotzdem will ich Dir einmal Deinen Code explizit sauber umwandeln:
string appDataVerzeichnis = Environment.GetEnvironmentVariable("appData"); string hamitVerzeichnis = Path.Combine(appDataVerzeichnis, "hamitgerkansprojects"); if(!Directory.Exists(hamitVerzeichnis)) Directory.CreateDirectory(hamitVerzeichnis);
Allerdings denke ich, es ist besser die reine .NET Methode zu benutzen, als die Umgebungsvariable - also etwa:string appDataVerzeichnis = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string hamitVerzeichnis = Path.Combine(appDataVerzeichnis, "hamitgerkansprojects"); if(!Directory.Exists(hamitVerzeichnis)) Directory.CreateDirectory(hamitVerzeichnis);
Wichtig ist auch, dass man im allgemeinen AppData-Verzeichnis normal Erstellerbesitzer-Berechtigungen hat.
Man sollte diesen Berechtigungstyp "verstehen". Er birgt gewisse Risiken.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:33
-
Hallo Hamit,
schau mal hier, da stehen zwei Lösungswege:
http://stackoverflow.com/questions/867485/c-getting-the-path-of-appdata
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:34
Alle Antworten
-
Hallo Hamit,
schau mal hier, da stehen zwei Lösungswege:
http://stackoverflow.com/questions/867485/c-getting-the-path-of-appdata
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:34
-
Hallo Hamit,
> Ich würde gern einige Dateien für mein Programm im AppData-Ordner speichern, wofür ich allerdings dort einen Unterordner anlegen müsste
Die Umgebungsvariable %APPDATA% verweist auf das Verzeichnis, in dem programmspezifische Daten für den aktuellen Roamingbenutzer gespeichert werden (
%LOCALAPPDATA% hingegen auf das lokale Verzeichnis für den aktuellen Benutzer). Auf diese Verzeichnisse verweisen ebenfalls zwei Enumerationselemente: Environment.SpecialForders.ApplicationData bzw. Environment.SpecialForders.LocalApplicationData.
Wenn Du aber Programmdaten für alle Benutzer Deines Programms speichern möchtest (vom Programm gemeinsam genutzte Daten), dann müßtest Du das neue Verzeichnis eher unter %ALLUSERSPROFILE%, d.h. Environment.SpecialForders.CommonApplicationData erstellen.
Da die Umgebungsvariablen in vielen Fällen nicht, oder nicht richtig gesetzt sind, empfiehlt sich eher die Verwendung von Environment.SpecialFolders.
Verwendest Du aber trotzdem Umgebungsvariablen, so mußt Du diese vor der Verwendung expandieren:string expandedPath = Environment.ExpandEnvironmentVariables("%appdata%//hamitgerkansprojects"); System.IO.Directory.CreateDirectory(expandedPath); // wird nur erstellt wenn nicht vorhanden
Generell ist es vorteilhaft wenn man Pfade über System.IO.Path.Combine zusammenfügt, z.B. string myDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData), "SubDirectory").
Vorsicht: Der Name des Verzeichnisses ("hamitgerkansprojects") verstößt logisch gegen einige Grundsätze:
1. Environment.SpecialFolders.ApplicationData ist für benutzerspezifische Daten der Applikation und nicht des Benutzers vorgesehen ("projects" legt nahe, dass es sich hier um Projekte von Hamit handelt). Diese sollten, wenn es sich um Dokumente handelt, am besten unter SpecialFolders.Personal/MyDocuments + Unterverz. abgelegt werden.
2. Die Erwähnung des Benutzernamens (Hamit) im Pfadnamen macht bei der Verwendung von Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) nicht viel Sinn, da hier alle Verzeichnisse benutzerbezogen sind und der Name sowieso schon im Pfad steht.
3. Normalerweise steht unter %appdata% als Verzeichnisname der Name der Anwendung, also z.B. C:\Users\Hamit Gerkan\AppData\Roaming\SuperApp.Das Speichern von Daten unter SpecialFolder.ApplicationData hat noch einen weiteren Haken. Wenn Deine Anwendung für alle Benutzer installiert wird, gibt es zur Installationszeit keinen korrekten Speicherort dafür, d.h. eventuelle Daten die Du vorab nach SpecialFolder.ApplicationData schreiben möchtest, dürfen nicht während der Installation sondern erst beim ersten Start der Anwendung nach ApplicationData geschrieben werden.
Auf die Probleme von ApplicationData bei der Verwendung von ClickOnce-Deployment, gehe ich hier nicht ein.Ach ja, fast hätte ich's vergessen: Du kannst natürlich außer über Umgebungsvariable, SpecialFoders-Enumerationselemente auch noch über Application.CommonAppDataPath, Application.LocalUserAppDataPath bzw. Application.UserAppDataPath auf bekannte Verzeichnisse zugreifen. Diese letzten drei Properties haben den Vorteil, dass sie je nachdem ob die Anwendung über ClickOnce oder normal installiert wurde, autom. auf entspr. Verzeichnisse verzweigen (ClickOnce => AppDomain.CurrentDomain.GetData("DataDirectory"), sonst => strukturierter Pfad z.B. Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData))\Firma\Produkt\Version).
Dazu kommen unter Windows 7 weitere Möglichkeiten hinzu, auf die ich hier ebenfalls nicht eingehe.
Environment.SpecialFolder Enumeration
http://msdn.microsoft.com/de-de/library/system.environment.specialfolder.aspxEnvironment.ExpandEnvironmentVariables-Methode:
http://msdn.microsoft.com/de-de/library/system.environment.expandenvironmentvariables.aspxKNOWNFOLDERID (unter Remarks stehen die Standardpfade):
http://msdn.microsoft.com/en-us/library/dd378457(v=vs.85).aspx
Technical requirements for the Windows 7 Client Software Logo Program
http://www.microsoft.com/download/en/details.aspx?id=3859
Gruß
Marcel
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:33
-
Hallo Hamit,
dazu ist einiges zu sagen. Im Prinzip solltest Du immer erstmal die .NET Methoden für die Pfade benutzen und nicht Dinge wie "%appdata%" obwohl das unter Windows sehr oft funktionieren wird. Ich verzichte mal auf eigene Bemerkungen, da diese Dinge sehr gut in den Artikeln beschrieben sind.
Also erstmal die wichtigsten Möglichkeiten dazu:
Pfad für die Anwendungsdaten eines Benutzers:
[Application.UserAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.userappdatapath.aspxPfad für die Anwendungsdaten eines lokalen Benutzers, der kein Roaming verwendet:
[Application.LocalUserAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.localuserappdatapath.aspxPfad für die Anwendungsdaten, die von allen Benutzern gemeinsam genutzt werden:
[Application.CommonAppDataPath-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.application.commonappdatapath.aspx
[Environment.SpecialFolder-Enumeration (System)]
http://msdn.microsoft.com/de-de/library/system.environment.specialfolder.aspx
CommonApplicationData:
Das Verzeichnis, das als allgemeines Repository für programmspezifische Daten verwendet
wird, die von allen Benutzern verwendet werden.
LocalApplicationData:
Das Verzeichnis, das als allgemeines Repository für programmspezifische Daten verwendet
wird, die von einem aktuellen Benutzer verwendet werden, der kein Roamingbenutzer ist.Hier detailliertere Möglichkeiten ab Vista und später, mit denen man sehr dedizierte Ordner-Positionen angeben kann:
[KNOWNFOLDERID (Windows)]
http://msdn.microsoft.com/en-us/library/dd378457(VS.85).aspx
[CSIDL (Windows)]
http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx -> CSIDL_APPDATA[ReadMe.txt - Shell known folder sample (CSShellKnownFolders)]
http://code.msdn.microsoft.com/CSShellKnownFolders-94aa920a/sourcecode?fileId=21702&pathId=1556858234
========================================Trotzdem will ich Dir einmal Deinen Code explizit sauber umwandeln:
string appDataVerzeichnis = Environment.GetEnvironmentVariable("appData"); string hamitVerzeichnis = Path.Combine(appDataVerzeichnis, "hamitgerkansprojects"); if(!Directory.Exists(hamitVerzeichnis)) Directory.CreateDirectory(hamitVerzeichnis);
Allerdings denke ich, es ist besser die reine .NET Methode zu benutzen, als die Umgebungsvariable - also etwa:string appDataVerzeichnis = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string hamitVerzeichnis = Path.Combine(appDataVerzeichnis, "hamitgerkansprojects"); if(!Directory.Exists(hamitVerzeichnis)) Directory.CreateDirectory(hamitVerzeichnis);
Wichtig ist auch, dass man im allgemeinen AppData-Verzeichnis normal Erstellerbesitzer-Berechtigungen hat.
Man sollte diesen Berechtigungstyp "verstehen". Er birgt gewisse Risiken.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 14. Juli 2011 15:33