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 9ac21a6b..e50f7a19 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..15f3c777 100644
--- a/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
+++ b/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
@@ -27,7 +27,10 @@ public IEnumerable GetInstalledPackages(string projectPath, boo
return Enumerable.Empty();
}
- return GetInstalledPackagesFromAssetsFile(includeTransitive, project);
+ if (project.IsPackageReferenceProject())
+ return GetInstalledPackagesFromAssetsFile(includeTransitive, project);
+
+ return PackagesConfigReader.GetPackages(project.GetPackagesConfigPath());
}
private IEnumerable GetInstalledPackagesFromAssetsFile(bool includeTransitive,
diff --git a/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs b/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs
index 40eeb00c..e8cf2d41 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,35 @@ 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();
+
+ if (OperatingSystem.IsWindows())
+ {
+ var mmc = new ManagementClass("root/cimv2/vs:MSFT_VSInstance");
+
+ foreach (ManagementBaseObject? 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/src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackageConfigReader.cs b/src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackageConfigReader.cs
new file mode 100644
index 00000000..ef8aba29
--- /dev/null
+++ b/src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackageConfigReader.cs
@@ -0,0 +1,17 @@
+using System.Xml.Linq;
+using NuGetUtility.Wrapper.NuGetWrapper.Versioning;
+
+namespace NuGetUtility.Wrapper.NuGetWrapper.Packaging.Core
+{
+ public static class PackagesConfigReader
+ {
+ public static IEnumerable GetPackages(string path)
+ {
+ var document = XDocument.Load(path);
+
+ var reader = new NuGet.Packaging.PackagesConfigReader(document);
+
+ return reader.GetPackages().Select(p => new PackageIdentity(p.PackageIdentity.Id, new WrappedNuGetVersion(p.PackageIdentity.Version)));
+ }
+ }
+}
diff --git a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
index 6cb0997c..194776db 100644
--- a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
+++ b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs
@@ -65,12 +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.That(exception?.Message, Is.EqualTo($"Invalid project structure detected. Currently only PackageReference projects are supported (Project: {path})"));
+ IEnumerable result = _uut!.GetInstalledPackages(path, false);
+
+ Assert.That(result.Count, Is.EqualTo(1));
}
}
}