Установка пакетов NuGet и разрешение ссылок с пользовательским типом проекта с использованием Common Project System

Я создаю тип проекта с помощью 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, ссылки также показывают желтый восклицательный знак, но даже когда мой пользовательский проект возвращает ту же информацию, ссылки все еще не разрешены. Там должны быть другие вещи, которые используются.

Я хотел подтвердить, что это может работать, но чтобы переопределить эту функцию, я обнаружил, что MSBuildNuGetProjectSystemFactory создал VsMSBuildProjectSystem класс на основе жестко закодированных идентификаторов типов проектов, и это внутренний класс. Кажется, он подключен при экспорте MSBuildNuGetProjectProvider который реализует 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 в своих собственных сборках, чтобы мой класс никогда не поднимался?

0 ответов

Другие вопросы по тегам