|
| 1 | +using System.Diagnostics.CodeAnalysis; |
| 2 | +using System.Reflection; |
| 3 | +using System.Runtime.Loader; |
1 | 4 | using System.Xml.Linq; |
2 | 5 | using Microsoft.Extensions.DependencyInjection; |
3 | 6 | using Microsoft.Extensions.FileProviders; |
@@ -354,8 +357,16 @@ public async Task<IEnumerable<InstalledPackage>> GetAllInstalledPackagesAsync() |
354 | 357 |
|
355 | 358 | if (!string.IsNullOrEmpty(packageManifest.Version)) |
356 | 359 | { |
| 360 | + // Always use package version from manifest |
357 | 361 | installedPackage.Version = packageManifest.Version; |
358 | 362 | } |
| 363 | + else if (string.IsNullOrEmpty(installedPackage.Version) && |
| 364 | + string.IsNullOrEmpty(installedPackage.PackageId) is false && |
| 365 | + TryGetAssemblyInformationalVersion(installedPackage.PackageId, out string? version)) |
| 366 | + { |
| 367 | + // Use version of the assembly with the same name as the package ID |
| 368 | + installedPackage.Version = version; |
| 369 | + } |
359 | 370 | } |
360 | 371 |
|
361 | 372 | // Return all packages with an ID or name in the package manifest or package migrations |
@@ -414,4 +425,20 @@ public Task<PagedModel<InstalledPackage>> GetInstalledPackagesFromMigrationPlans |
414 | 425 |
|
415 | 426 | return packageFile.CreateReadStream(); |
416 | 427 | } |
| 428 | + |
| 429 | + private static bool TryGetAssemblyInformationalVersion(string name, [NotNullWhen(true)] out string? version) |
| 430 | + { |
| 431 | + foreach (Assembly assembly in AssemblyLoadContext.Default.Assemblies) |
| 432 | + { |
| 433 | + AssemblyName assemblyName = assembly.GetName(); |
| 434 | + if (string.Equals(assemblyName.Name, name, StringComparison.OrdinalIgnoreCase) && |
| 435 | + assembly.TryGetInformationalVersion(out version)) |
| 436 | + { |
| 437 | + return true; |
| 438 | + } |
| 439 | + } |
| 440 | + |
| 441 | + version = null; |
| 442 | + return false; |
| 443 | + } |
417 | 444 | } |
0 commit comments