1

我正在使用 Visual Studio Common Project System 创建一个项目类型并连接了 NuGet 包管理器。但是,当我安装软件包时,它会失败并出现以下错误:

Attempting to gather dependency information for package '[PackageName]' with respect to project '[ProjectName]', targeting '.NETFramework,Version=v4.7'
Gathering dependency information took 3.23 ms
Attempting to resolve dependencies for package '[PackageName]' with DependencyBehavior 'Lowest'
Resolving dependency information took 0 ms
Resolving actions to install package '[PackageName]'
Resolved actions to install package '[PackageName]'
Retrieving package '[AssemblyName] [Version]' from '[Source]'.
Adding package '[PackageName]' to folder '[ProjectDirectory]\packages'
Added package '[PackageName]' to folder '[ProjectDirectory]\packages'
Install failed. Rolling back...
Package '[PackageName]' does not exist in project '[ProjectName]'
Removing package '[PackageName]' from folder '[ProjectDirectory]\packages'
Removed package '[PackageName]' from folder '[ProjectDirectory]\packages'
Executing nuget actions took 1.17 sec
Failed to add reference to '[AssemblyName]'.
  Unable to find a type of reference that is appropriate for this file: "[ProjectDirectory]\packages\[PackageName]\lib\net46\[AssemblyName].dll".
Time Elapsed: 00:00:01.2728560
========== Finished ==========

我反编译了 NuGet 程序集并对其进行了调试,发现错误发生在NuGet.PackageManagement.VisualStudio.VsMSBuildProjectSystem.AddReferenceAsync这一行reference = References.Add(assemblyFullPath);。所以我尝试执行相同的代码并在尝试“System”和“[FullAssemblyPath]”时得到相同的错误。

Unable to find a type of reference that is appropriate for this file: [Assembly].

VsMSBuildProjectSystem 源代码

我尝试调试一个普通的 Visual Basic 项目,发现它执行的命令略有不同References3.AddFiles(new[] { assemblyFullPath }, out var referencesArray);,这是因为 References 对象可以强制转换为 References3。事实证明,Visual Basic 项目是一种VSLangProj80.VSProject2类型,而我的自定义项目是一种VSLangProj.VSProject类型。

我还注意到,在我的自定义项目类型中,引用旁边有一个黄色感叹号,因为它们尚未解决。我相信这是问题的根源。我不确定 Visual Studio 如何解析引用,但通过调试我能够发现使用了 MSBuild 目标ResolveAssemblyReferences。当我在 Visual Basic 项目文件中覆盖它时,引用也显示黄色感叹号,但即使我的自定义项目返回相同的信息,引用仍然未解析。必须有其他使用的东西。

我想确认它可以工作,但要覆盖我发现基于硬编码项目类型 GUIDMSBuildNuGetProjectSystemFactory创建类的函数,它是一个内部类。VsMSBuildProjectSystem它似乎是通过导出MSBuildNuGetProjectProvider该 implements来连接的INuGetProjectProvider。我想用我自己的提供者覆盖它并用这段代码返回一个自定义实现,但不幸的是它永远不会被实例化。MSBuildNuGetProjectProvider 源代码

<Export(GetType(INuGetProjectProvider))>
<Name("MSBuildNuGetProjectProvider")>
<Microsoft.VisualStudio.Utilities.Order(After:="ProjectJsonProjectProvider")>
Friend Class MyNuGetProjectProvider : Implements INuGetProjectProvider

    <ImportingConstructor>
    Public Sub New(threadingService As IVsProjectThreadingService)
        Me.New(AsyncServiceProvider.GlobalProvider, threadingService)
    End Sub

    Public Sub New(vsServiceProvider As Microsoft.VisualStudio.Shell.IAsyncServiceProvider, threadingService As IVsProjectThreadingService)

    End Sub

    Public ReadOnly Property ProjectType As RuntimeTypeHandle Implements INuGetProjectProvider.ProjectType
        Get
            Return GetType(MSBuildNuGetProject).TypeHandle
        End Get
    End Property

    Public Async Function TryCreateNuGetProjectAsync(project As IVsProjectAdapter, context As ProjectProviderContext, forceProjectType As Boolean) As Task(Of NuGetProject) Implements INuGetProjectProvider.TryCreateNuGetProjectAsync
        Dim projectSystem As New TestProjectSystem(project, context.ProjectContext)

        Await projectSystem.InitializeProperties()

        Return New MSBuildNuGetProject(projectSystem, context.PackagesPathFactory.Invoke, project.ProjectDirectory)
    End Function

End Class

所以我只是破解了它并使用反射将我的类添加到MSBuildNuGetProjectSystemFactory并执行我的自定义类,覆盖添加引用的方法,而不是什么都不做。添加 NuGet 包成功,但是引用当然没有添加到项目中。MSBuildNuGetProjectSystemFactory 源代码

Friend Class TestProjectSystem : Inherits VsMSBuildProjectSystem

    Private mProjectAdapter As IVsProjectAdapter

    Public Sub New(a As IVsProjectAdapter, c As INuGetProjectContext)
        MyBase.New(a, c)

        Me.mProjectAdapter = a
    End Sub


    Public Overrides Async Function AddReferenceAsync(referencePath As String) As Threading.Tasks.Task
        'Dim project = TryCast(Me.mProjectAdapter.Project.Object, VSLangProj.VSProject)

        'project.References.Add(referencePath)
    End Function

End Class

所以我仍然不知道 Visual Studio 是如何解析程序集的,我希望一旦修复它,NuGet 包管理器也能正常工作。我认为它可能会使用IVsDesignTimeAssemblyResolution,但我永远无法通过 MEF 实例化我的类。我想知道它是否在 Visual Studio 非托管代码中处理并且不存在扩展点,考虑到它是一个不同的项目类正在创建。

如果是这种情况,那么我认为我可以使用该INuGetProjectProvider界面来覆盖添加引用并通过直接编辑 XML 文件来完成。但为什么我的INuGetProjectProvider实现从未通过 MEF 实例化?我尝试将 Order 属性更改为 0 和 1000。Visual Studio MEF 在其自己的程序集中是否有 Nuget 的范围,所以我的课程永远不会被拾起?

4

0 回答 0