Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

single file publish: AppContext.BaseDirectory doesn't point to apphost directory #3704

Closed
dasMulli opened this issue Jul 29, 2019 · 11 comments
Closed
Assignees
Milestone

Comments

@dasMulli
Copy link
Contributor

Steps to reproduce

  1. Create a hello world program:
static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    Console.WriteLine($"Base Directory: {AppContext.BaseDirectory}");
    Console.WriteLine($"Assembly Location: {typeof(Program).Assembly.Location}");
}
  1. Publish self contained - dotnet publish -c Release -r win-x64 -p:PublishSingleFile=True --self-contained false (or self-contained)

  2. Run the resulting exe file.

Expected behavior

According to the design document, AppContext.BaseDirectory is the API that developers should use to access the path where the app host resides.

The app context base directory should therefore not be in AppData\Local\Temp\.net\.

Background: I want to use this directory to load override config files.

Actual behavior

C:\demos\testcons\bin\Release\netcoreapp3.0\win-x64\publish>testcons.exe
Hello World!
Base Directory: C:\Users\ullrimar\AppData\Local\Temp\.net\testcons\53kpwgv0.3mq\
Assembly Location: C:\Users\ullrimar\AppData\Local\Temp\.net\testcons\53kpwgv0.3mq\testcons.dll

Environment data

>dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview7-012821
 Commit:    6348f1068a

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100-preview7-012821\

Host (useful for support):
  Version: 3.0.0-preview7-27912-14
  Commit:  4da6ee6450

cc @vitek-karas

@dasMulli
Copy link
Contributor Author

@swaroop-sridhar is there any other path at the moment that points to the app host directory and/or name?

@swaroop-sridhar
Copy link
Contributor

In the current version, we simply extract the contents of the bundle to a directory on the disk, and declare that directory as the base-directory. This choice aims to preserve compatibility for apps that assume that apcontext.basedirectory contains the app.dll. In the current version, we'll need to use native APIs such as GetModuleFileName to get the path of the native AppHost.

In subsequent versions, once the app.dll is processed directly from the bundle, the design doc discusses options to set AppContext.BaseDirectory. The current proposal is to set it to the location of the AppHost.

@swaroop-sridhar
Copy link
Contributor

You could also try using: Process.GetCurrentProcess().MainModule.FileName as suggested here: https://github.com/dotnet/coreclr/issues/20287#issuecomment-506590901

@dasMulli
Copy link
Contributor Author

dasMulli commented Aug 7, 2019

That works, thanks!

Is this (esp. AppContext.BaseDirectory) subject to change? If not, I'd ask for the design document to be in line with the actual implementation, or hint at which parts are part of .NET Core 3.0.

@swaroop-sridhar
Copy link
Contributor

swaroop-sridhar commented Aug 15, 2019

Yes @dasMulli the value of AppContext.BaseDirectory is open question in the next version of .net core, -- because when we load assemblies directly from the bundle, there's no extraction directory. My current thinking is that it will point to the host directory, as indicated in the design doc.

@karataliu
Copy link

Can make AppContext.BaseDirectory an independent way for getting run root?
If using Process.GetCurrentProcess().MainModule.FileName, it works fine with single file app, but when run in vs test, the value returned is 'dotnet.exe'.

@theimowski
Copy link
Contributor

FYI seems like starting with .NET SDK 3.1.201, the Diagnostics.Process.GetCurrentProcess().MainModule.FileName changed behaviour with regards to non-single file publish.

with .NET SDK 3.1.101:
I could use Diagnostics.Process.GetCurrentProcess().MainModule.FileName for both single-file publish, and debug development (dotnet watch run) and it returned the base directory in both cases, but

in .NET SDK 3.1.201:
In debug development mode (dotnet watch run), Diagnostics.Process.GetCurrentProcess().MainModule.FileName returns the dotnet executable (e.g. /usr/local/share/dotnet/dotnet) so I had to amend my code to following:

  let baseDir =
#if DEBUG
    AppContext.BaseDirectory
#else
    Diagnostics.Process.GetCurrentProcess().MainModule.FileName
    |> IO.Path.GetDirectoryName
#endif

@dasMulli
Copy link
Contributor Author

dasMulli commented Apr 1, 2020

@theimowski are you running this on macOS?

In order to comply with notarization requirements, the signed binary (/usr/local/share/dotnet/dotnet) is used so users don't get too many errors.

You can get the old behavior again by specifying this in your project file:

<PropertyGroup>
  <UseAppHost>true</UseAppHost>
</PropertyGroup>

See https://docs.microsoft.com/en-us/dotnet/core/install/macos-notarization-issues for more details

@theimowski
Copy link
Contributor

Thanks @dasMulli yup I'm running on macOS and missed the notarization update. The UseAppHost property did the job for me 👍

@ghost
Copy link

ghost commented May 16, 2020

Tagging subscribers to this area: @swaroop-sridhar
Notify danmosemsft if you want to be subscribed.

@swaroop-sridhar
Copy link
Contributor

This issue is fixed in .net5

@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants