Wie sollte eine .NET Core 3.0-Web-API-Anwendung mit einer einzelnen Datei so konfiguriert werden, dass nach der appsettings.json
Datei gesucht wird, die sich in demselben Verzeichnis befindet, in dem die Einzeldateianwendung erstellt wurde?
Nach dem Rennen
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Das Verzeichnis sieht folgendermaßen aus:
XX/XX/XXXX XX:XX PM <DIR> .
XX/XX/XXXX XX:XX PM <DIR> ..
XX/XX/XXXX XX:XX PM 134 appsettings.json
XX/XX/XXXX XX:XX PM 92,899,983 APPNAME.exe
XX/XX/XXXX XX:XX PM 541 web.config
3 File(s) 92,900,658 bytes
Der Versuch, etwas auszuführen, APPNAME.exe
führt jedoch zu folgendem Fehler
An exception occurred, System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs\appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
...
Ich habe Lösungen aus einer ähnlichen, aber unterschiedlichen Frage sowie aus anderen Fragen zum Stapelüberlauf ausprobiert .
Ich habe versucht, folgendes zu übergeben SetBasePath()
Directory.GetCurrentDirectory()
environment.ContentRootPath
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
Jeder führte zu demselben Fehler.
Die Wurzel des Problems ist, dass die PublishSingleFile
Binärdatei entpackt und aus einem temp
Verzeichnis ausgeführt wird.
Bei dieser App mit einer einzelnen Datei war der gesuchte Speicherort appsettings.json
das folgende Verzeichnis:
C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs
Alle oben genannten Methoden verweisen auf den Ort, an den die Datei entpackt wird, der sich von dem Ort unterscheidet, an dem sie ausgeführt wurde.
quelle
Wenn Sie damit einverstanden sind, dass Dateien zur Laufzeit außerhalb der ausführbaren Datei verwendet werden, können Sie die gewünschten Dateien einfach in csproj markieren. Diese Methode ermöglicht Live-Änderungen und dergleichen an einem bekannten Ort.
Wenn dies nicht akzeptabel ist und NUR eine einzelne Datei enthalten darf, übergebe ich den aus einer einzelnen Datei extrahierten Pfad als Stammpfad in meinem Host-Setup. Dadurch können die Konfiguration und der Rasierer (den ich später hinzufüge) die Dateien wie gewohnt finden.
Beachten Sie, dass Sie außerdem Folgendes benötigen, um wirklich eine einzelne Datei und keinen PDB zu erstellen:
quelle
Meine Anwendung befindet sich unter .NET Core 3.1, wird als einzelne Datei veröffentlicht und als Windows-Dienst ausgeführt (was sich möglicherweise auf das Problem auswirkt oder nicht).
Die vorgeschlagene Lösung mit
Process.GetCurrentProcess().MainModule.FileName
als Inhaltsstamm funktioniert für mich, aber nur, wenn ich den Inhaltsstamm an der richtigen Stelle einstelle:Das funktioniert:
Das funktioniert nicht:
quelle