Sdk: Cannot run global tool after installing it, must open new command prompt

Created on 11 Jan 2018  路  47Comments  路  Source: dotnet/sdk

After I have successfully installed a global tool I am not able to run it without opening a new command prompt:

C:\Users\daroth\Desktop\test>dotnet install tool dotnet-dev-certs --version 2.1.0-preview1-28051

The installation succeeded. If there is no other instruction. You can type the following command in shell directly to invoke: dotnet-dev-certs

C:\Users\daroth\Desktop\test>dotnet dev-certs -h
No executable found matching command "dotnet-dev-certs"

C:\Users\daroth\Desktop\test>dotnet-dev-certs -h
'dotnet-dev-certs' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\daroth\Desktop\test>dotnet dev-certs
No executable found matching command "dotnet-dev-certs"
tool

Most helpful comment

I've the same error when using dotnet tool install --global *** in the new Azure Pipelines flow.

My command is like:

dotnet tool install --global dotnet-sonarscanner

This command outputs this:

Since you just installed the .NET Core SDK, you will need to reopen the Command Prompt window before running the tool you installed.
You can invoke the tool using the following command: dotnet-sonarscanner
Tool 'dotnet-sonarscanner' (version '4.3.1') was successfully installed.

And the next step will fail (running the above command in the same step or a different script step make no difference)

No executable found matching command "dotnet-sonarscanner"

All 47 comments

Did you just installed SDK? It requires a restart of command prompt in order for PATH in registry to work. However there should be an error message to tell the user to restart.

@danroth27 can you give us the info @wli3 is asking for above?

We could either add these windows specific code

or add instruction to reopen cmd

Yes, opening a new command prompt works, but I don't think that's the user experience we want. You should be able to install a global tool and use it immediately. That's how npm global tools work, right?

/cc @KathleenDollard

This is only a problem for when dotnet is first installed and I believe is a similar behavior as npm actually. It is not a matter of I ran install or not. It is a matter of I just got this CLI.

Oh, so this is a one time thing?

one time per user

Ah, ok. I think that's fine then.

Will can you put the new text in this issue? I think it would tidy up this issue prior to closing it.

We updated that "If there are no further instructions" and I thought it was a but more clear in the install that the restart was needed.

I haven't put the change in yet. According to https://github.com/dotnet/cli/issues/8369

We want to use the following

The installation succeeded and you can run the tool by typing: dotnet-dev-certs
(If you the tool is not found, try restarting your shell)

Cool, that will the new text be in Preview 1?

No, it won't be in preview 1. But that's what we decided so far. Do we want to add more to it according to this thread?

@KathleenDollard Above is not in preview 1. What in preview 1 is issue description's version.

could something be done to test if the directory that the shim was written to is not yet on the current PATH?

@dasMulli Something similar is added. However, I think it is not working properly due to, in Windows it cannot distinguish between what will be available(in registry) and what is available in the session

With official preview release (macOS):

dotnet install tool dotnet-dev-certs -g --version 2.1.0-preview1-final
Since you just installed the .NET Core SDK, you will need to reopen terminal before running the tool you installed.
The installation succeeded. If there are no further instructions, you can type the following command in shell directly to invoke: dotnet-dev-certs

and:

dotnet-dev-certs
command not found: dotnet-dev-certs

I'd suggest to rephrase it to dotnet dev-certs - is this works
thanks!

I've the same error when using dotnet tool install --global *** in the new Azure Pipelines flow.

My command is like:

dotnet tool install --global dotnet-sonarscanner

This command outputs this:

Since you just installed the .NET Core SDK, you will need to reopen the Command Prompt window before running the tool you installed.
You can invoke the tool using the following command: dotnet-sonarscanner
Tool 'dotnet-sonarscanner' (version '4.3.1') was successfully installed.

And the next step will fail (running the above command in the same step or a different script step make no difference)

No executable found matching command "dotnet-sonarscanner"

@StefH

If you just installed the SDK, the path to your global tools you need to restart the shell for the path to global tools to be recognized.

Are you installing and running via a script? (where this would be quite problematic)

If so @wli3 can he set the path explicitly in the script to avoid the problem?

You could add %UserProfile%/.dotnet/tools/ to your path before running the command.
Although, in script, we recommend using --too-path with explicit location instead of install it globally. And call the tool with full path.

+1 for the tool path. an example vsts / azure pipelines config usage can bee seen in msbuild:
https://github.com/Microsoft/msbuild/blob/542125d86fca51bbfce5cebd6f3efd3bb36549b0/.vsts-dotnet.yml#L28-L39

Hi @dasMulli ; keep seeing you everywhere...
Hi @wli3 : thanks for your solution.

For now I just solved it by providing the full path to the executable, so:

%USERPROFILE%\.dotnet\tools\dotnet-sonarscanner

See also linked issue https://github.com/Microsoft/vsts-tasks/issues/8291

Some problem here . However, in old VSTS pipelines it works. It Azure DevOps it does not.

@ignatandrei Same here. VSTS Pipeline stopped working -- unable to find the tool installed in a previous step.

@cosmoKenney : After reporting as a bug (https://developercommunity.visualstudio.com/content/problem/340067/install-global-tool.html?childToView=343864#comment-343864 ) , found an workaround until the bug is solved:

See the https://github.com/ignatandrei/stankins/blob/master/azure-pipelines.yml

steps:

  • script: |
    dotnet tool install --tool-path . dotnetsay
    .\dotnetsay
    displayName: 'Command Line Script'

( I do prefer putting on current dir rather to be based on %USERPROFILE%.dotnet\tools\ folder that can change at a future release . It is still a workaround)

@ignatandrei I really don't understand the yaml. Did you switch to a CMD task?

Yes.

@wli3 in an automated scenario like Azure pipelines(previously VSTS) this is a big problem. There is no way to open a new shell to mitigate this. Also, just adding a better message does not solve this problem. Why does dotnet tool require this extra manual step? Npm works just fine. At the minimum, dotnet tool install -g should be adding the location to PATH.
Can we re-activate this issue?

+1 on reopening this issue. Using the CMD step [workaround] to install the tool using --tool-path doesn't work if you install a tool to some arbitrary folder. Then if you use the tool in a following step in the pipeline, you still don't have access to the tool. If there were a variable you could use with a path in both steps that would help mitigate the issue.

I created a new thread for Azure DevOps CI issue https://github.com/dotnet/cli/issues/10059

Does this limitation apply in Linux as well, or are the environment variables available as soon as the tool is installed without having to restart the shell?

@wli3

Hi @stamminator

Does this limitation apply in Linux as well, or are the environment variables available as soon as the tool is installed without having to restart the shell?

This applies to Linux if you install it via package manager like apt-get. You need to re log in your shell in order to _source_ the script we put in /etc/profile.d which will append to $PATH.

Sorry, it's a bit unclear whether the original complaint was ever addressed.

Does dotnet now set the PATH correctly for globally installed tools in the original scenario, or must we instead use --tool-path and put that in the PATH manually to get it to work?

@dbsanfte The problem with needing to restart the shell is in how some shell/OS's work. That waste original issue. This only needs to be done once, after installing the .NET SDK.

I'm not sure that's the issue you're referring to.

What if I cannot restart? I'm using a Dockerfile to build an AZP agent...

I am facing the same issue: I'm in a Docker container, at build time on our build server.

@KathleenDollard It should be trivial to update the PATH of the current shell session in addition to the system one.

It should be trivial to update the PATH of the current shell session in addition to the system one.

This is actually not trivial by the design of Unix. PATH like any other environment variable is stored in current shell session. There is no API available to change PATH in an application for the current session.

However, if you are in Docker you could run export PATH="$PATH:$HOME/.dotnet/tools" to make it available. Or relogin bash shell session by command

You're right actually, on second thought it isn't so trivial.

I'm fine with sourcing .bashrc if that's where you're updating my PATH.

Still kind of sucks though.

@dbsanfte We'd love to have a better experience on this and remain open to ideas. But we're also committed to playing nice on all the platforms we support.

@dbsanfte we did not add the export to bashrc. it is in /etc/profile.d/dotnet-cli-tools-bin-path.sh

Can you make a symbolic link in /usr/local/bin? That's in most everyone's PATH, definitely the default PATH in Ubuntu at any rate.

helm, kubectl, tiller, etc put their symbolic links there.

That would require sudo for every dotnet tool install command. Since /usr/local/bin is not writable by current user

For a global install (presumably for all users), sudo would seem to be acceptable.

as a AzureDevOps user creating a CI/CD pipeline or creating a global tool that is to be used in a AzureDevOps pipeline guidance is needed on why/how/what steps are required & the order of these steps to allow tools to work as expected.

Agreed with @3GDXC, I can't seem to find good guidance here.
The URL refrerenced above in "@satrapu
GLobal tools are now installed and used in the same script block" has syntax that doesn't work as it has both global tools and a tool path.
Is the solution to just use --tools-path and reference all tool locations in code from that install folder?

Hey @adamtuliper, please check the following script block from my latest pipeline:

- script: >-
      dotnet tool install dotnet-reportgenerator-globaltool 
      --global
      --version $(ReportGenerator_Version)
    name: 'install_code_coverage_report_generator'
    displayName: 'Install code coverage report generator tool'
    env:
      DOTNET_SKIP_FIRST_TIME_EXPERIENCE: $(DotNetSkipFirstTimeExperience)
      DOTNET_CLI_TELEMETRY_OPTOUT: $(DotNetCliTelemetryOptOut)
      COREHOST_TRACE: $(CoreHostTrace)

I no longer use the --tool-path argument, just the --global one.

@satrapu Thanks for that. Having another way is good to know. There's a catch in what you wrote above, it is working as a byproduct of the .NET Core install by updating PATH. It just so happens you are doing a specific version install to make that happen rather than exporting the tools folder to the path. One thing to consider - outside of that workaround a local tools folder may be faster and easier than managing/updating version information and an additional SDK install task. I can simplify by using a local tool, your scenario may not allow that though.

  # Install specific .NET Core SDK version used for building the application.
  # See more here: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops.
  # Installing a specific .NET Core SDK version is needed to avoid installing a .NET Core global tool in a following task and 
  # then have Azure DevOps complain that it cannot find it.
  # This issue is documented here: https://github.com/Microsoft/azure-pipelines-tasks/issues/8291.
  - task: UseDotNet@2
    name: 'install_dotnetcore_sdk_required_by_application'
    displayName: 'Install .NET Core SDK required by application'
    inputs:
      packageType: 'sdk'
      version: $(DotNetCore_SDK_Version)

vs

    - script: |
        dotnet tool install --tool-path tools dotnet-reportgenerator-globaltool
        ./tools/reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/coverlet/reports -reporttypes:"Cobertura"
      displayName: Create Code coverage report
Was this page helpful?
0 / 5 - 0 ratings