dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

Relative path in deps.json is ignored for assemblies from the app #3525

Open vitek-karas opened 5 years ago

vitek-karas commented 5 years ago

The .deps.json can specify relative path for any asset. The directory portion of that path is ignored for normal assemblies which are part of the app though.

Repro:

dotnet new console
dotnet add package Newtonsoft.Json
dotnet build

Now in the bin/Debug/netcoreapp3.0 create a sub directory and move the Newtonsoft.Json.dll into it. Edit the app.deps.json to point to sub/Newtonsoft.Json.dll like this:

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v3.0",
    "signature": "6596ed3d155c0211dab1fd90ba9d71b725c973ba"
  },
  "compilationOptions": {},
  "targets": {
    ".NETCoreApp,Version=v3.0": {
      "Newtonsoft.Json/12.0.1": {
        "runtime": {
          "sub/Newtonsoft.Json.dll": {
          }

Run the app via dotnet app.dll.

Expected: The host should be able to find the Newtonsoft.Json.dll since it exists in the right relative path.

Actual: The host fails to find the file, and it fails with error like this:

Error:
  An assembly specified in the application dependencies manifest (app.deps.json) was not found:
    package: 'Newtonsoft.Json', version: '12.0.1'
    path: 'sub/Newtonsoft.Json.dll'

Which is very misleading, as the path contains the subdirectory, but the host doesn't use it to look up the file. This can be observed in the trace:

Processing TPA for deps entry [Newtonsoft.Json, 12.0.1, sub/Newtonsoft.Json.dll]
  Considering entry [Newtonsoft.Json/12.0.1/sub/Newtonsoft.Json.dll], probe dir [], probe fx level:0, entry fx level:0
    Local path query did not exist F:\AppModel\repro\DepsJsonRelative\bin\Debug\netcoreapp3.0\Newtonsoft.Json.dll
liesauer commented 5 years ago

hi, i am working on an awesome tool called NetCoreBeauty that makes the .net core application directory looks beauty recently, and got the same problem. here's the things happends, if i cd into app base directory, and then run my app with command ./myapp or just double-click it, everything works properly, but when i try to run my app at other directory such as ~ with command /path/to/my/app, it fails to load the assemblies, and then i found something interesting.

Ignoring additional probing path libraries as it does not exist.
blah blah blah...
-- Listing probe configurations...
probe_config_t: probe=[] deps-dir-probe=[1]
Adding tpa entry: /Users/imac/go/src/Projects/NetCoreBeauty/NetCoreBeautyNugetTest/bin/Release/netcoreapp2.1/osx-x64/publish/NetCoreBeautyTest.dll, AssemblyVersion: , FileVersion:
Processing TPA for deps entry [NetCoreBeautyTest, 1.0.0, ./NetCoreBeautyTest.dll]
  Considering entry [NetCoreBeautyTest/1.0.0/./NetCoreBeautyTest.dll], probe dir [], probe fx level:0, entry fx level:0
    Local path query exists /Users/imac/go/src/Projects/NetCoreBeauty/NetCoreBeautyNugetTest/bin/Release/netcoreapp2.1/osx-x64/publish/NetCoreBeautyTest.dll
    Probed deps dir and matched '/Users/imac/go/src/Projects/NetCoreBeauty/NetCoreBeautyNugetTest/bin/Release/netcoreapp2.1/osx-x64/publish/NetCoreBeautyTest.dll'
Processing TPA for deps entry [runtime.osx-x64.Microsoft.NETCore.App, 2.1.9, ./Microsoft.CSharp.dll]
  Considering entry [runtime.osx-x64.Microsoft.NETCore.App/2.1.9/./Microsoft.CSharp.dll], probe dir [], probe fx level:0, entry fx level:0
    Local path query did not exist /Users/imac/go/src/Projects/NetCoreBeauty/NetCoreBeautyNugetTest/bin/Release/netcoreapp2.1/osx-x64/publish/Microsoft.CSharp.dll
    Skipping... not found in deps dir '/Users/imac/go/src/Projects/NetCoreBeauty/NetCoreBeautyNugetTest/bin/Release/netcoreapp2.1/osx-x64/publish/'
    Skipping... not found in probe dir ''
Error:
  An assembly specified in the application dependencies manifest (NetCoreBeautyTest.deps.json) was not found:
    package: 'runtime.osx-x64.Microsoft.NETCore.App', version: '2.1.9'
    path: './Microsoft.CSharp.dll'

so i think i have fight it out why it fails to load the assemblies, it tries to resolve my additionalProbingPaths with current working directory, not the application base directory! therefore it makes sense why the first time it works and second time it fails. that is the cause!

tomazv commented 4 years ago

Is there any update on this?

We are porting our desktop app to .net core and we have a critical issue related to this.

We are using self-contained deployment model. Our app consists of multiple executables - some are Console and some WPF apps. In order to make root directory clean and preserve disk space, we use common libs directory where we put dependencies for all executables. We also need to use different versions of the same library - for example, WindowsBase.dll is different for Console and WPF apps.

We have used following steps:

  1. Updated runtimeconfig.json to use "libs" directory using additionalProbingPaths.
  2. Put all dependencies in the "libs" directory and use subdirectories for versioning. For instance, WindowsBase.dll for console and WPF apps are in directories libs/runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0 and libs/runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0 respectively.
  3. Updated deps.json file to find all dependencies. We used "path" in the libraries section:
    "libraries": {
      "runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0": {
        "type": "runtimepack",
        "serviceable": false,
        "sha512": "",
        "path": "./runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0"
      },
      "runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0": {
        "type": "runtimepack",
        "serviceable": false,
        "sha512": "",
        "path": "./runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0"
      }

This works fine if application is executed from the app directory, but breaks if executed from another directory. The issue is that paths are relative to working directory and not app directory. The proposed fix in issue dotnet/core-setup#7534 solved this, but we would like to use a supported solution.

liesauer commented 4 years ago

@tomazv i don't think this will be fixed in a short time...may will be fixed in .net5...that is why i create NetCoreBeauty project, actually, i have used my solution for a long time and it works perfectly as i expect. hope this tool help you too.

pawelFelcyn commented 3 months ago

Is there any update on this?

We are porting our desktop app to .net core and we have a critical issue related to this.

We are using self-contained deployment model. Our app consists of multiple executables - some are Console and some WPF apps. In order to make root directory clean and preserve disk space, we use common libs directory where we put dependencies for all executables. We also need to use different versions of the same library - for example, WindowsBase.dll is different for Console and WPF apps.

We have used following steps:

  1. Updated runtimeconfig.json to use "libs" directory using additionalProbingPaths.
  2. Put all dependencies in the "libs" directory and use subdirectories for versioning. For instance, WindowsBase.dll for console and WPF apps are in directories libs/runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0 and libs/runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0 respectively.
  3. Updated deps.json file to find all dependencies. We used "path" in the libraries section:
    "libraries": {
      "runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0": {
        "type": "runtimepack",
        "serviceable": false,
        "sha512": "",
        "path": "./runtimepack.Microsoft.NETCore.App.Runtime.win-x86/3.1.0"
      },
      "runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0": {
        "type": "runtimepack",
        "serviceable": false,
        "sha512": "",
        "path": "./runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x86/3.1.0"
      }

This works fine if application is executed from the app directory, but breaks if executed from another directory. The issue is that paths are relative to working directory and not app directory. The proposed fix in issue dotnet/core-setup#7534 solved this, but we would like to use a supported solution.

I know it's been a long time, but we are experiencing exactly the same issue. Have you solved this? If so, do you remember how?