tareqimbasher / NetPad

A cross-platform C# editor and playground.
MIT License
1.31k stars 67 forks source link

Nuget package error - Could not locate install path after package was installed. #148

Closed ugurdal closed 8 months ago

ugurdal commented 9 months ago

Hi there,

I'm trying to add nuget package to my script and I'm getting the following error. I would be happy if you could help me, thanks.

Package Cache Folder: C:\Users{user_name}\AppData\Local\NetPad\Cache\Packages

using Microsoft.Extensions.DependencyInjection;

var serviceProvider = new ServiceCollection()
    .AddScoped<ICustomer, Lcw>()
    .AddScoped<ICustomer, Gratis>()
    .BuildServiceProvider();

var serv = serviceProvider.GetRequiredService<ICustomer>();
serv.Account.Dump();

public interface ICustomer
{
    string Get();
    Account Account {get;}
}

public enum Account
{
    Lcw = 1,
    Gratis = 2
}

public class Lcw : ICustomer
{
    public string Get() => "Lcw";
    public Account Account => Account.Lcw;
}

public class Gratis : ICustomer
{
    public string Get() => "Gratis";
    public Account Account => Account.Gratis;
}
System.Exception: Could not locate install path after package was installed. Package ID: Microsoft.Extensions.DependencyInjection.Abstractions, Version: 8.0.0
   at NetPad.Packages.NuGetPackageProvider.InstallPackagesAsync(PackageIdentity explicitPackageToInstallIdentity, IEnumerable`1 packagesToInstall, SourceCacheContext sourceCacheContext, ILogger logger, CancellationToken cancellationToken) in /home/tips/Source/TIPS/NetPad/src/Infrastructure/NetPad.Infrastructure/Packages/NuGetPackageProvider.cs:line 530
   at NetPad.Packages.NuGetPackageProvider.InstallPackagesAsync(PackageIdentity explicitPackageToInstallIdentity, IEnumerable`1 packagesToInstall, SourceCacheContext sourceCacheContext, ILogger logger, CancellationToken cancellationToken) in /home/tips/Source/TIPS/NetPad/src/Infrastructure/NetPad.Infrastructure/Packages/NuGetPackageProvider.cs:line 561
   at NetPad.Packages.NuGetPackageProvider.InstallPackageAsync(String packageId, String packageVersion, DotNetFrameworkVersion dotNetFrameworkVersion) in /home/tips/Source/TIPS/NetPad/src/Infrastructure/NetPad.Infrastructure/Packages/NuGetPackageProvider.cs:line 156
   at NetPad.Packages.NuGetPackageProvider.GetPackageAndDependencyAssetsAsync(String packageId, String packageVersion, DotNetFrameworkVersion dotNetFrameworkVersion) in /home/tips/Source/TIPS/NetPad/src/Infrastructure/NetPad.Infrastructure/Packages/NuGetPackageProvider.cs:line 231
   at NetPad.Utilities.ReferenceUtil.GetAssetsAsync(IEnumerable`1 references, DotNetFrameworkVersion dotNetFrameworkVersion, IPackageProvider packageProvider) in /home/tips/Source/TIPS/NetPad/src/Core/NetPad.Domain/Utilities/ReferenceUtil.cs:line 26
   at NetPad.Runtimes.ExternalProcessScriptRuntime.GetRunDependencies(RunOptions runOptions) in /home/tips/Source/TIPS/NetPad/src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessScriptRuntime.Setup.cs:line 33
   at NetPad.Runtimes.ExternalProcessScriptRuntime.RunScriptAsync(RunOptions runOptions) in /home/tips/Source/TIPS/NetPad/src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessScriptRuntime.cs:line 81

I can see the packages are downloaded to the relevant directory

image

tareqimbasher commented 9 months ago

Hello! That's interesting. I would like to inspect the folder structure under Microsoft.Extensions.DependencyInjection.Abstractions, if you could ZIP the Abstractions folder from your screenshot and send it over that would be helpful.

ugurdal commented 9 months ago

microsoft.extensions.dependencyinjection.abstractions.zip Of course I added the folder, thanks.

tareqimbasher commented 8 months ago

Not sure if you tried this already but could you try deleting the 8.0.0 folder inside microsoft.extensions.dependencyinjection.abstractions folder and try running a script that has Microsoft.Extensions.Dependencyinjection.Abstractions referenced.

The only thing I found that stood out was that there's supposed to be a netpad.json file inside that 8.0.0 directory that NetPad creates when it downloads the nuget package, in the folder you gave me, its missing. That might mean you are not referencing the Microsoft.Extensions.Dependencyinjection.Abstractions lib in your script using (F4 > Packages) and instead you might be referencing the .dll assembly directly by browsing for it on disk? That's probably not the case but just want to confirm.

ugurdal commented 8 months ago

I tried as you said but I still get the same error. Here is script properties, I did not reference the .dll directly.

image image

tareqimbasher commented 8 months ago

OK well that's a head scratcher because its not showing in the Local Cache section on the left side, and it should! To rule out its not some weird upgrade issue or something, can you try these steps:

  1. Remove the reference from the script
  2. Close NetPad
  3. Completely delete the C:\Users\{user_name}\AppData\Local\NetPad\Cache\Packages folder
  4. Start NetPad back up
  5. Add the reference to the script again, Save the properties window and then run the script

Thank you for reporting this.

ugurdal commented 8 months ago

I think its related to the package that I'm trying to install. Cause when I click + Reference button on Microsoft.Extensions.DependencyInjection package, following error appears in the middle of the bottom status bar. And no netpad.json file in it. But I've try different packages and they took maybe 1 second longer to install and I saw the yellow status bar after I've clicked + Reference button. I don't saw any yellow status bar when I try to install Microsoft.Extensions.DependencyInjection package

I hope this difference gives us a clue.

image

Is there any way to debug or somehow see detailed error messages while the package is being installed?

Thanks,

ugurdal commented 8 months ago

I've found it. It's related to Turkish I problem. In the src/Infrastructure/NetPad.Infrastructure/Packages/NuGetPackageProvider.cs - GetInstallPath method, I've change ToLower -> ToLowerInvariant. And it works, I've debugged it.

You see, in Turkish uppercase letter I get lowers to ı, not i. And lowercase letter i gets upper to İ.

private string? GetInstallPath(NugetPackageIdentity packageIdentity)
{
    bool TryGetPath(string? path, out string? newPath) ...

    string dirPath = Path.Combine(GetNuGetCacheDirectoryPath(), packageIdentity.Id.ToLowerInvariant(),
        packageIdentity.Version.ToString().ToLowerInvariant());

    if (TryGetPath(dirPath, out string? installPath))
        return installPath;

    return null;
}
tareqimbasher commented 8 months ago

Got it, ya that looks like the problem indeed. I'll merge your PR and take a closer look at other locations where this same change is needed. Thank you for taking the time to figure out the issue and submit a fix!

tareqimbasher commented 8 months ago

PR #152 is merged. This will go out with next release (v0.7.0)