diff --git a/src/NuGetUtility/Extensions/ProjectExtensions.cs b/src/NuGetUtility/Extensions/ProjectExtensions.cs
index 5f9c466b..95a650bd 100644
--- a/src/NuGetUtility/Extensions/ProjectExtensions.cs
+++ b/src/NuGetUtility/Extensions/ProjectExtensions.cs
@@ -19,6 +19,11 @@ public static bool IsPackageReferenceProject(this IProject project)
!project.HasPackagesConfigFile();
}
+ public static string GetPackagesConfigPath(this IProject project)
+ {
+ return Path.Join(Path.GetDirectoryName(project.FullPath), PackagesConfigFileName);
+ }
+
private static bool HasPackagesConfigFile(this IProject project)
{
return project.GetEvaluatedIncludes().Any(include => include?.Equals(PackagesConfigFileName) ?? false);
diff --git a/src/NuGetUtility/NuGetUtility.csproj b/src/NuGetUtility/NuGetUtility.csproj
index f369d1fd..50b20301 100644
--- a/src/NuGetUtility/NuGetUtility.csproj
+++ b/src/NuGetUtility/NuGetUtility.csproj
@@ -30,6 +30,7 @@
+
diff --git a/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs b/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
index b438348e..6d02e7f3 100644
--- a/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
+++ b/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
@@ -1,7 +1,9 @@
+using System.Xml.Linq;
using NuGetUtility.Extensions;
using NuGetUtility.Wrapper.MsBuildWrapper;
using NuGetUtility.Wrapper.NuGetWrapper.Packaging.Core;
using NuGetUtility.Wrapper.NuGetWrapper.ProjectModel;
+using NuGetUtility.Wrapper.NuGetWrapper.Versioning;
namespace NuGetUtility.ReferencedPackagesReader
{
@@ -27,9 +29,26 @@ public IEnumerable GetInstalledPackages(string projectPath, boo
return Enumerable.Empty();
}
- return GetInstalledPackagesFromAssetsFile(includeTransitive, project);
+ if (project.IsPackageReferenceProject())
+ return GetInstalledPackagesFromAssetsFile(includeTransitive, project);
+
+ return GetInstalledPackagesFromPackagesConfig(project);
+ }
+
+ private IEnumerable GetInstalledPackagesFromPackagesConfig(IProject project)
+ {
+ var xml = XElement.Load(project.GetPackagesConfigPath());
+
+ return xml.Descendants("package").Select(p => ToPackageIdentity(p));
}
+ private PackageIdentity ToPackageIdentity(XElement xlm)
+ {
+ var packageid = (string) xlm.Attribute("id");
+ var version = (string) xlm.Attribute("version");
+
+ return new PackageIdentity(packageid, new WrappedNuGetVersion(version));
+ }
private IEnumerable GetInstalledPackagesFromAssetsFile(bool includeTransitive,
IProject project)
{
diff --git a/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs b/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs
index 40eeb00c..f5e51139 100644
--- a/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs
+++ b/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs
@@ -1,3 +1,4 @@
+using System.Management;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
@@ -12,10 +13,17 @@ namespace NuGetUtility.Wrapper.MsBuildWrapper
public class MsBuildAbstraction : IMsBuildAbstraction
{
private const string CollectPackageReferences = "CollectPackageReferences";
+ private readonly Dictionary _project_props = new ();
public MsBuildAbstraction()
{
RegisterMsBuildLocatorIfNeeded();
+
+ // to support VC-projects we need to workaround : https://github.com/3F/MvsSln/issues/1
+ // adding 'VCTargetsPath' to Project::GlobalProperties seem to be enough
+
+ if (GetBestVCTargetsPath() is string path)
+ _project_props.Add("VCTargetsPath", $"{path}\\");
}
public IEnumerable GetPackageReferencesFromProjectForFramework(IProject project,
@@ -40,16 +48,9 @@ public IProject GetProject(string projectPath)
{
ProjectRootElement rootElement = TryGetProjectRootElement(projectPath);
- var project = new Project(rootElement);
- var projectWrapper = new ProjectWrapper(project);
-
- if (!projectWrapper.IsPackageReferenceProject())
- {
- throw new MsBuildAbstractionException(
- $"Invalid project structure detected. Currently only PackageReference projects are supported (Project: {project.FullPath})");
- }
+ var project = new Project(rootElement, _project_props, null);
- return projectWrapper;
+ return new ProjectWrapper(project);
}
public IEnumerable GetProjectsFromSolution(string inputPath)
@@ -59,6 +60,32 @@ public IEnumerable GetProjectsFromSolution(string inputPath)
return sln.ProjectsInOrder.Select(p => p.AbsolutePath);
}
+ private static string? GetBestVCTargetsPath()
+ {
+ var cpp_props = new List();
+
+ foreach (string path in GetVisualStudioInstallPaths())
+ cpp_props.AddRange(new DirectoryInfo(path).GetFiles("Microsoft.Cpp.Default.props", SearchOption.AllDirectories));
+
+ // if multiple, assume most recent 'LastWriteTime' property is 'best'
+ return cpp_props.OrderBy(f => f.LastWriteTime).LastOrDefault()?.DirectoryName;
+ }
+
+ private static IEnumerable GetVisualStudioInstallPaths()
+ {
+ // https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2022#using-windows-management-instrumentation-wmi
+
+ var result = new List();
+
+ var mmc = new ManagementClass("root/cimv2/vs:MSFT_VSInstance");
+
+ foreach (var vs_instance in mmc.GetInstances())
+ if (vs_instance["InstallLocation"] is string install_path)
+ result.Add(install_path);
+
+ return result;
+ }
+
private static void RegisterMsBuildLocatorIfNeeded()
{
if (!MSBuildLocator.IsRegistered)
diff --git a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
index b4630c50..920eb0dd 100644
--- a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
+++ b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
@@ -65,14 +65,13 @@ public void GetInstalledPackagesShould_ReturnEmptyEnumerableForProjectsWithoutPa
[Test]
[Platform(Include = "Win")]
- public void GetInstalledPackagesShould_ThrowMsBuildAbstractionException_If_ProjectUsesPackagesConfig()
+ public void GetInstalledPackagesShould_ReturnPackagesForPackagesConfigProject()
{
string path = Path.GetFullPath("../../../../targets/PackagesConfigProject/PackagesConfigProject.csproj");
- MsBuildAbstractionException? exception = Assert.Throws(() => _uut!.GetInstalledPackages(path, false));
- Assert.AreEqual(
- $"Invalid project structure detected. Currently only PackageReference projects are supported (Project: {path})",
- exception?.Message);
+ IEnumerable result = _uut!.GetInstalledPackages(path, false);
+
+ Assert.That(result.Count, Is.EqualTo(1));
}
}
}