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

Could not load file or assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' #12736

Closed
HoytRen opened this issue Jul 11, 2023 · 6 comments

Comments

@HoytRen
Copy link

HoytRen commented Jul 11, 2023

NuGet Product Used

NuGet.exe

Product Version

6.6.1.2

Worked before?

I don't know.

Impact

I'm unable to use this version

Repro Steps & Context

I create a new .net project and build the .exe and .dll.

then I try nuget.exe spec -a .\bin\Debug\net7.0\MyApp.dll

It sends out the error. I don't understand how could I don't have the assembly since I build the dll and obviously be able to run MyApp.exe.

Verbose Logs

No response

@zivkan
Copy link
Member

zivkan commented Jul 11, 2023

@HoytRen nuget.exe doesn't support PackageReference projects, and even if a spec was created, if the project uses any packages, the dependencies won't be reported correctly. Actually, I think nuget pack will report an error saying it's not supported. We should probably do the same for nuget spec.

Are you aware of dotnet pack? If so, is there a reason you're still trying to create a nuspec?

@erdembayar erdembayar added Functionality:Pack WaitingForCustomer Applied when a NuGet triage person needs more info from the OP Product:NuGet.exe NuGet.exe and removed Triage:Untriaged labels Jul 11, 2023
@HoytRen
Copy link
Author

HoytRen commented Jul 12, 2023

@zivkan Thank you very much for your help. I'm trying to create a common dependence walker tool for project analysis. It currently working for Golang because the dependence management of Golang is much simpler, but I create it with .net because there are better developing tools for me. And I plan to support more languages. Then it will be weird if it doesn't support .net project when the first release. That's why I'm working on .nuspec. Since every package on NuGet.org has a .nuspec, it will be easier if I could generate .nuspec for any target project, then I only need to parse the .nuspec file and don't care about the complex dependence management of .net. Maybe there are better approaches that you could give me some prompts. Martin Ullrich mentioned RunResolvePackageDependencies of MSBuild on stackoverflow, it seems easy but as I tried, it doesn't work now, just as 'nuget spec'.

My tool generate output like:
image

@ghost ghost added WaitingForClientTeam Customer replied, needs attention from client team. Do not apply this label manually. and removed WaitingForCustomer Applied when a NuGet triage person needs more info from the OP labels Jul 12, 2023
@zivkan
Copy link
Member

zivkan commented Jul 12, 2023

@HoytRen unfortunately you have a very difficult path ahead of you if you want to analyze a compiled binary and report a package graph.

If you're willing to show an assembly graph, rather than a package graph, have a look at System.Reflection.Metadata. It takes a little bit of time to wrap your head around the API, because when you ask for something, like assembly references, it returns a handle, and then you have to call another API to get string (names) from the handle. But once you learn that, it becomes very easy to extract assembly metadata, like referenced assemblies, without having to load the assembly's references. Decoding methods and types is very difficult, but getting referenced assemblies, or assembly attributes, is fairly straight forward.

The reason that nuget.exe is failing, but the app works at runtime, is because the app is .NET 7 (hence needing System.Runtime.dll version 7.0.0.0), whereas nuget.exe is a .NET Framework app, hence will probably have access to System.Runtime.dll version 4.x.y.z). nuget spec was written years before .NET Core was created, so it's something that never mattered. Since .NET Core (including .NET 5+, that dropped the "Core" name) only supports PackageReference, and nuget.exe pack and nuget.exe spec only supports packages.config, it's outside of nuget.exe's design goals. Since nuget is open source, someone could change it to use system.reflection.metadata, so that it doesn't need to load referenced assemblies. But I don't see our team ever spending time to implement this ourselves, as it doesn't help our team's primary focus: build tooling. Also, if someone did implement it, I don't know if we'd accept the pull request, since it adds a lot of risk of introducing new bugs, for something that doesn't benefit nuget spec in supported scenarios. However, even if someone changed that, nuget spec will never create dependencies in the nuspec with the project's original packages.config, so this still won't do what you want.

dotnet list package --include-transitive does something similar to what you want, but it shows a flat list rather than a graph. Since nuget's open source, you can look at the source to see how it does it (basically, it requires restore to run first, then it reads the obj\project.assets.json file).

Finally, here are three issues I can immediately think of as problems if you want to show a package graph, rather than the assembly graph, if all you have is a compiled binary, not the project file.

  1. package version != assembly version

Newtonsoft.Json is an example that immediately comes to mind. Consider package versions 13.0.1 and 13.0.2. Both contain Newtonsoft.Json.dll assembly version 13.0.0.0. There is also no package version 13.0.0[.0].

  1. Packages can contain more than 1 assembly

While we recommend package authors only put 1 assembly per package, and to use package dependencies, not everyone follows our advise. Therefore, a package Contoso.Something might contain both Contoso.Something.dll and Contoso.Helper.dll. There probably won't be any package Contoso.Helper, but if there is, that doesn't mean an app with with dll is using the helper package, it could be using the "something" package.

  1. package id != assembly name

Similar to the multiple assembly issue, there's no enforcement that the package id must be the same name.

Recently I saw a package on nuget.org that had 2 assemblies, neither of which matched the package ID. Unfortunately I can't remember what the package ID is, otherwise it would be a perfect example to demonstrate the last two issues above.

@ghost ghost added WaitingForCustomer Applied when a NuGet triage person needs more info from the OP and removed WaitingForClientTeam Customer replied, needs attention from client team. Do not apply this label manually. labels Jul 12, 2023
@zivkan zivkan closed this as not planned Won't fix, can't repro, duplicate, stale Jul 12, 2023
@ghost ghost removed the WaitingForCustomer Applied when a NuGet triage person needs more info from the OP label Jul 12, 2023
@HoytRen
Copy link
Author

HoytRen commented Jul 12, 2023

@zivkan This information is very useful and detailed, and saves me tons of time. I will take the easier approach as an assembly graph for now, and try others later.

I learned reflection already when I made other tools, don't worry, but without your recommendation, I may not take it for this tool.

I only plan to support the projects with source code, but I misunderstand the function of 'nuget spec -a' as you said when I see the generated .nuspec is full of tokens with my .csproj but no dependence. I originally want to avoid creating the .nuspec with dependence manually for the users because mapping "net461" to ".NETFramework 4.6.1" is really tricky for automation.

Thank you again for your valuable suggestions.

@zivkan
Copy link
Member

zivkan commented Jul 12, 2023

You can reference the NuGet.Frameworks package, and then use NuGetFramework.Parse(string) and compare two instances to see that strings "net461", ".NETFramework461" and ".NETFramework,Version=4.6.1" all represent the same framework.

@HoytRen
Copy link
Author

HoytRen commented Jul 12, 2023

You are really my help angle!

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

No branches or pull requests

3 participants