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

global tool - appsettings.json #9730

Closed
dazinator opened this issue Sep 10, 2018 · 13 comments
Closed

global tool - appsettings.json #9730

dazinator opened this issue Sep 10, 2018 · 13 comments
Assignees
Labels
Milestone

Comments

@dazinator
Copy link

Steps to reproduce

I am developing a global tool, and the first thing it does is in it's entry point, is load some configuration from a local appsettings.json file.

var config = new ConfigurationBuilder()
	.SetBasePath(Directory.GetCurrentDirectory())
	.AddJsonFile("appsettings.json")
        .AddCommandLine(args)																	.Build();

My csproj looks like this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>    
    <AssemblyName>dotnet-foo</AssemblyName>
    <RuntimeIdentifiers>win-x64;win-x86;osx.10.10-x64;osx.10.11-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;ubuntu.16.10-x64;centos.7-x64;rhel.7.2-x64;debian.8-x64;fedora.24-x64;opensuse.42.1-x64</RuntimeIdentifiers>
    <PackageType>DotnetCliTool</PackageType>
    <IsPackable>true</IsPackable>
    <PackAsTool>true</PackAsTool>
  </PropertyGroup>

<ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

I dotnet pack the tool and can see the appsettings.json file included along side the .dll inside the nuget package.
I upload the nuget package to an internal feed.
I install the tool somewhere using: dotnet tool install dotnet-foo --tool-path ./my-tool --add-source "https://packages.foo.com/nuget/App/"

The tool installs successfully.
However when I run the tool, it crashes as it cannot find the appsettings.json file.
Looking in the tool install directory, there is no appsettings.json file.

Expected behaviour

Tool can be distributed with content files such as appsettings.json

Actual behavior

Tool is installed missing content files such as appsettings.json.

Environment data

dotnet --info output:

Version: 2.1.401
Commit: 91b1c13

Runtime Environment:
OS Name: Windows
OS Version: 10.0.17134
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.1.401\

Host (useful for support):
Version: 2.1.3
Commit: 124038c13e

@livarcocc
Copy link
Contributor

@peterhuene @wli3

@wli3 wli3 self-assigned this Sep 10, 2018
@JCanlett
Copy link

JCanlett commented Oct 24, 2018

+1 I am having same problem. If I run the tool from any folder where the appsettings exist it is fine. However when running from root or anywhere else, it seems to use the context of that folder as the location of the app rather than where the app and content actually is. Also it is changing the structure a lot! .dotnet\tools includes the .exe bootstrapping the app, but the actual app is burried deep under the < ToolName >< Version >\ Folder.

Any progress on this yet?

@wli3
Copy link

wli3 commented Oct 25, 2018

So this is what i tried. I created https://github.com/wli3/temp-repro-appsettings-missing and run the following command to install it on ./my-tool
image

I cannot repro the file missing. However, if I install dotnet-foo i could get an error. It might be a packageid collision? There is a package called dotnet-foo happen to be in your feed?

@JCanlett
Copy link

JCanlett commented Oct 26, 2018 via email

@wli3
Copy link

wli3 commented Oct 26, 2018

@JCanlett sorry, what do you mean by "I think it is only for global tool install." Please see my screen shot. I did use dotnet tool install to install it

@dazinator
Copy link
Author

dazinator commented Oct 27, 2018 via email

@wli3
Copy link

wli3 commented Oct 27, 2018

@dazinator in the original issue it is --tool-path. And I tried both. And no repro.

Could you tried to name the package something unique? I did find there is a dotnet-foo in the nuget.org feed

https://www.nuget.org/packages/dotnet-foo/

@dazinator
Copy link
Author

dazinator commented Oct 27, 2018

My package isn't called dotnet-foo, it's called bs-utils and on an internal proget feed. I used dotnet-foo in the issue because I didn't think the name of the package mattered for repro purposes. Let me compare it to your sample on Monday to see what the difference could be. If I can't work it out i'll see if I can upload the actual package or create a minimal repro.

@JCanlett
Copy link

@wli3 for 100% repro every time - You need first package a dotnet core tool. Deploy that package to an azure devops NuGet feed. Once deployed use
dotnet tool install -g <%mytool%>
Do not use the --tool-path switch.

Once the tool installs globally, its added to the path environment variable. However when you run a dotnet tool from the root of C:\ for example, the current working directory is c:\ which will not have appsettings.json and thus the app crashes in the startup. @dazinator this your experience as well?

@JCanlett
Copy link

@JCanlett sorry, what do you mean by "I think it is only for global tool install." Please see my screen shot. I did use dotnet tool install to install it

dotnet tool install -g <~ this is global vs local install

@wli3
Copy link

wli3 commented Oct 28, 2018

@JCanlett @dazinator Thank you! I get a repro. Is that what looks like? Just like what you said, appsettings.json is not on the current directory. I did not cd out of the project directory so there is a appsettings.json in working directory
image

@wli3
Copy link

wli3 commented Oct 28, 2018

@dazinator in the program you explicitly state the BasePath is the current directory. And once you install it on your path the CurrentDirectory depends on what is your shell at. CLI does carry the appsettings.json file but it is stored in the same directory of dlls. To access it you need to read it like the following

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;

namespace appsettingrepro
{
    class Program
    {
        static void Main(string[] args)
        {
            string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            var config = new ConfigurationBuilder()
	        .SetBasePath(assemblyFolder) // !!
	        .AddJsonFile("appsettings.json")
            .Build();

            var dict = new Dictionary<string, string>();
            config.GetSection("section0").Bind(dict);
            Console.WriteLine(dict["key0"]);
        }
    }
}

@wli3 wli3 closed this as completed Oct 28, 2018
@msftgits msftgits transferred this issue from dotnet/cli Jan 31, 2020
@msftgits msftgits added this to the 3.0.1xx milestone Jan 31, 2020
@JWString
Copy link

JWString commented Oct 15, 2022

I recently ran into the same problem. I was attempting to install a simplified asp.net utility as a dotnet global tool. It was configured to suppress the usual logging, but after deployment as a dotnet tool, the application could not locate appsettings.json and the needed settings were not applied.

To fix this, I added this to the startup portion of my utility:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions()
{
    ContentRootPath = Directory.GetParent(Assembly.GetExecutingAssembly().Location)?.FullName
});

Edit: I should note that the only reason I figured this out is because of this Microsoft article. If I'm not mistaken, this is intentional behavior. It seems reasonable that you might want to have a global tool that does not read from any appsettings.json file included in the distribution, but instead, from the current working directory. However, it's also a little counterintuitive when you have a different use case in mind and the settings are clearly included with the distribution. It would be nice if there were a switch available in settings where we could change this behavior for tool packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants