查找SDK风格项目的依赖
Find dependencies of SDK-style projects
在 Visual Studio 扩展中,我需要遍历加载的解决方案中的所有项目并找到所有依赖项(NuGet 包和程序集)。以下代码适用于旧的非 SDK 样式项目,但不适用于新的 SDK 样式项目。
var dte = ApplicationObject; // DTE object
if (dte == null || dte.Solution == null || !dte.Solution.IsOpen)
{
return;
}
foreach (Project project in dte.Solution.Projects)
{
var vsProj = project.Object as VSProject;
if (vsProj == null || vsProj.References == null)
{
// Project not loaded
continue;
}
foreach (Reference reference in vsProj.References)
{
if (reference.SourceProject != null
|| reference.Type != prjReferenceType.prjReferenceTypeAssembly)
{
// Skip over non assembly references
continue;
}
// reference.Name contains the reference name
}
}
在新的 SDK 样式项目中,"references" 现在称为依赖项,但 VSProject
上没有这样的 属性。那么SDK风格的项目怎么获取呢?
So what is the way to get this for SDK-style projects?
恐怕答案是否定的。这可能是一个与VS2019 SDK和新SDK项目系统相关的问题。
并且此问题专门发生在 IVsSolutionEvents.OnAfterOpenSolution
事件中。我试图在 OnQueryCloseSolution
事件或 Command Item
的点击事件中调用类似的代码,但对于其中包含 one .net core
应用程序的相同解决方案,它都运行良好。
我认为这可能是一个问题,因为解决方案和项目不为空(我输出 xx.sln 和 xx.csproj),但它无法从 reference.Name
vsProj.References
。它在关闭解决方案时有效,但现在打开 solution.For 时得到空列表,我发现没有有效的解决方法使其有效。
问题已报告给DC,如果有人对此感兴趣,可以跟踪问题here。
VS2019工程是.net core 3.1库工程,打开解决方案后如下代码。实际上是检索存储在 nuget 位置中的引用的路径位置:
C:\Users\xxxxx\.nuget\packages\subsonic.core.dal.2.1\lib\netstandard2.1\SubSonic.Core.DataAccessLayer.dll
public string ResolveAssemblyReference(string assemblyReference)
{
ThreadHelper.ThrowIfNotOnUIThread();
string path = EngineHost.ResolveAssemblyReference(assemblyReference);
if (path.Equals(assemblyReference, StringComparison.Ordinal) &&
!foundAssembly.IsMatch(path))
{ // failed to find the assembly, could it be referenced via a project reference?
if (GetService(typeof(DTE)) is DTE dTE)
{
foreach (Project project in dTE.Solution.Projects)
{
if (project.Object is VSProject vsProject)
{
path = ResolveAssemblyReferenceByProject(assemblyReference, vsProject.References);
}
else if (project.Object is VsWebSite.VSWebSite vsWebSite)
{
path = ResolveAssemblyReferenceByProject(assemblyReference, vsWebSite.References);
}
}
}
if (!foundAssembly.IsMatch(path))
{
LogError(false, SubSonicCoreErrors.FileNotFound, -1, -1, $"{assemblyReference}.dll");
}
}
return path;
}
private string ResolveAssemblyReferenceByProject(string assemblyReference, References references)
{
foreach (Reference reference in references)
{
if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
{ // found the reference
return reference.Path;
}
}
return assemblyReference;
}
private string ResolveAssemblyReferenceByProject(string assemblyReference, VsWebSite.AssemblyReferences references)
{
foreach (VsWebSite.AssemblyReference reference in references)
{
if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
{ // found the reference
return reference.FullPath;
}
}
return assemblyReference;
}
在 Visual Studio 扩展中,我需要遍历加载的解决方案中的所有项目并找到所有依赖项(NuGet 包和程序集)。以下代码适用于旧的非 SDK 样式项目,但不适用于新的 SDK 样式项目。
var dte = ApplicationObject; // DTE object
if (dte == null || dte.Solution == null || !dte.Solution.IsOpen)
{
return;
}
foreach (Project project in dte.Solution.Projects)
{
var vsProj = project.Object as VSProject;
if (vsProj == null || vsProj.References == null)
{
// Project not loaded
continue;
}
foreach (Reference reference in vsProj.References)
{
if (reference.SourceProject != null
|| reference.Type != prjReferenceType.prjReferenceTypeAssembly)
{
// Skip over non assembly references
continue;
}
// reference.Name contains the reference name
}
}
在新的 SDK 样式项目中,"references" 现在称为依赖项,但 VSProject
上没有这样的 属性。那么SDK风格的项目怎么获取呢?
So what is the way to get this for SDK-style projects?
恐怕答案是否定的。这可能是一个与VS2019 SDK和新SDK项目系统相关的问题。
并且此问题专门发生在 IVsSolutionEvents.OnAfterOpenSolution
事件中。我试图在 OnQueryCloseSolution
事件或 Command Item
的点击事件中调用类似的代码,但对于其中包含 one .net core
应用程序的相同解决方案,它都运行良好。
我认为这可能是一个问题,因为解决方案和项目不为空(我输出 xx.sln 和 xx.csproj),但它无法从 reference.Name
vsProj.References
。它在关闭解决方案时有效,但现在打开 solution.For 时得到空列表,我发现没有有效的解决方法使其有效。
问题已报告给DC,如果有人对此感兴趣,可以跟踪问题here。
VS2019工程是.net core 3.1库工程,打开解决方案后如下代码。实际上是检索存储在 nuget 位置中的引用的路径位置:
C:\Users\xxxxx\.nuget\packages\subsonic.core.dal.2.1\lib\netstandard2.1\SubSonic.Core.DataAccessLayer.dll
public string ResolveAssemblyReference(string assemblyReference)
{
ThreadHelper.ThrowIfNotOnUIThread();
string path = EngineHost.ResolveAssemblyReference(assemblyReference);
if (path.Equals(assemblyReference, StringComparison.Ordinal) &&
!foundAssembly.IsMatch(path))
{ // failed to find the assembly, could it be referenced via a project reference?
if (GetService(typeof(DTE)) is DTE dTE)
{
foreach (Project project in dTE.Solution.Projects)
{
if (project.Object is VSProject vsProject)
{
path = ResolveAssemblyReferenceByProject(assemblyReference, vsProject.References);
}
else if (project.Object is VsWebSite.VSWebSite vsWebSite)
{
path = ResolveAssemblyReferenceByProject(assemblyReference, vsWebSite.References);
}
}
}
if (!foundAssembly.IsMatch(path))
{
LogError(false, SubSonicCoreErrors.FileNotFound, -1, -1, $"{assemblyReference}.dll");
}
}
return path;
}
private string ResolveAssemblyReferenceByProject(string assemblyReference, References references)
{
foreach (Reference reference in references)
{
if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
{ // found the reference
return reference.Path;
}
}
return assemblyReference;
}
private string ResolveAssemblyReferenceByProject(string assemblyReference, VsWebSite.AssemblyReferences references)
{
foreach (VsWebSite.AssemblyReference reference in references)
{
if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
{ // found the reference
return reference.FullPath;
}
}
return assemblyReference;
}