Mein Projekt hat eine Ordnerstruktur in der Größenordnung von:
Auf dem Server (der im Ordner Project/Server läuft) verweise ich auf den Ordner wie folgt:
var rootFolder = Directory.GetCurrentDirectory();
rootFolder = rootFolder.Substring(0,
rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
PathToData = Path.GetFullPath(Path.Combine(rootFolder, "Data"));
var Parser = Parser();
var d = new FileStream(Path.Combine(PathToData, $"{dataFileName}.txt"), FileMode.Open);
var fs = new StreamReader(d, Encoding.UTF8);
Auf meinem Windows-Rechner funktioniert dieser Code einwandfrei, da Directory.GetCurrentDirectory()
auf den aktuellen Ordner verweist, und wenn ich
rootFolder.Substring(0, rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
auf den Stammordner des Projekts verweist (nicht auf den bin- oder debug-Ordner).
Aber als ich es auf einem Mac ausführte, bekam ich "Directory.GetCurrentDirectory()
" schickte mich zu /usr/
Wie kann ich relative Pfade in meinem Projekt finden? Wo sollte ich den Datenordner so speichern, dass er für alle Unterprojekte in der Lösung leicht zugänglich ist - insbesondere für das Kestrel-Server-Projekt? Ich ziehe es vor, ihn nicht im wwwroot-Ordner zu speichern, da der Datenordner von einem anderen Mitglied des Teams verwaltet wird und ich nur auf die neueste Version zugreifen möchte. Welche Möglichkeiten habe ich?
Je nachdem, wo Sie sich in der Kestrel-Pipeline befinden - wenn Sie Zugriff auf IConfiguration
(Startup.cs
-Konstruktor) oder IHostingEnvironment
haben, können Sie entweder das IHostingEnvironment
in Ihren Konstruktor einfügen oder einfach den Schlüssel von der Konfiguration anfordern.
IHostingEnvironment
in Startup.cs
Constructorpublic Startup(IConfiguration configuration, IHostingEnvironment env)
{
var contentRoot = env.ContentRootPath;
}
public Startup(IConfiguration configuration)
{
var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
Wie bereits beantwortet (und zurückgezogen). Um das Basisverzeichnis zu erhalten, d.h. den Ort der laufenden Assembly, verwenden Sie nicht Directory.GetCurrentDirectory(), sondern holen Sie es aus IHostingEnvironment.ContentRootPath.
private IHostingEnvironment _hostingEnvironment;
private string projectRootFolder;
public Program(IHostingEnvironment env)
{
_hostingEnvironment = env;
projectRootFolder = env.ContentRootPath.Substring(0,
env.ContentRootPath.LastIndexOf(@"\ProjectRoot\", StringComparison.Ordinal) + @"\ProjectRoot\".Length);
}
Allerdings ist mir ein weiterer Fehler unterlaufen: Ich hatte das ContentRoot Directory beim Start auf Directory.GetCurrentDirectory() gesetzt und damit den von mir gewünschten Standardwert unterlaufen! Hier habe ich die fehlerhafte Zeile auskommentiert:
public static void Main(string[] args)
{
var host = new WebHostBuilder().UseKestrel()
// .UseContentRoot(Directory.GetCurrentDirectory()) //<== The mistake
.UseIISIntegration()
.UseStartup<Program>()
.Build();
host.Run();
}
Jetzt läuft es richtig - ich kann jetzt zu Unterordnern meines Projektstamms navigieren mit:
var pathToData = Path.GetFullPath(Path.Combine(projectRootFolder, "data"));
Ich erkannte meinen Fehler durch das Lesen von BaseDirectory vs. Current Directory und @CodeNotFound fand Antwort (die zurückgezogen wurde, weil es nicht funktionierte wegen der oben genannten Fehler), die im Grunde kann hier gefunden werden: Getting WebRoot Path and Content Root Path in Asp.net Core
Schauen Sie mal hier: https://stackoverflow.com/questions/6041332/best-way-to-get-application-folder-path
Um von dort zu zitieren:
System.IO.Directory.GetCurrentDirectory()
gibt das aktuelle Verzeichnis zurück, das der Ordner sein kann oder auch nicht, in dem sich die Anwendung befindet. Dasselbe gilt für Environment.CurrentDirectory. Für den Fall, dass Sie in einer DLL-Datei verwenden, wird der Pfad zurückgegeben, in dem der Prozess läuft (dies gilt insbesondere für ASP.NET).