簡體   English   中英

如何創建安裝最新的NuGet依賴項的項目模板

[英]How to create a project template that installs latest NuGet dependencies

我要創建一個模板,以安裝最新版本的NuGet軟件包及其所有依賴項。 使用NuGet.VisualStudio.TemplateWizard最常見解決方案NuGet.VisualStudio.TemplateWizard安裝指定的程序包版本,並且不解析任何依賴項。 基本上,我想在創建使用模板的項目時運行Install-Package example

如何創建安裝最新的NuGet依賴項的項目模板?

顯然,您的要求很明確。 但是我們不建議您這樣做。 因為更新軟件包將破壞模板。

我們知道的是,預安裝的軟件包可以使用模板向導工作。 實例化模板時,將調用一個特殊的向導。 該向導將加載需要安裝的軟件包列表,並將該信息傳遞給適當的NuGet API。

此外,向導中還需要idversion屬性,即使有較新的版本,也會用於安裝軟件包的版本。 這樣可以防止程序包更新破壞模板,從而可以選擇使用模板將程序包更新給開發人員。

而且,開發人員更新軟件包是一件非常簡單的事情。 開發人員可以根據自己的要求更新某些軟件包,而無需更新所有軟件包。

找到2種方法來做到這一點。 新的.csproj標准支持PackageReference指令,以包括NuGet程序包,並支持版本通配符,並且優先使用最高版本。 但這目前IWizard漏洞,因此我最終實現了自己的IWizard ,其功能類似於NuGet的默認向導,但安裝了最新的軟件包和依賴項:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using EnvDTE;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TemplateWizard;
using NuGet.VisualStudio;
using Task = System.Threading.Tasks.Task;

namespace Example
{
    public class NuGetTemplateWizard : IWizard
    {
        List<string> _packages;

        public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            if (customParams.Length > 0) {
                var vstemplate = XDocument.Load((string)customParams[0]);
                _packages = vstemplate.Root
                    .ElementsNoNamespace("WizardData")
                    .ElementsNoNamespace("packages")
                    .ElementsNoNamespace("package")
                    .Select(pkg => pkg.Attribute("id").Value)
                    .ToList();
            }
        }

        public void ProjectFinishedGenerating(Project project)
        {
            Task.Run(delegate {
                var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
                var _installer = componentModel.GetService<IVsPackageInstaller2>();

                foreach (var package in _packages) {
                    _installer.InstallLatestPackage(null, project, package, false, false);
                }
            });
        }

        public bool ShouldAddProjectItem(string filePath) { return true; }
        public void BeforeOpeningFile(ProjectItem projectItem) { }
        public void ProjectItemFinishedGenerating(ProjectItem projectItem) { }
        public void RunFinished() { }
    }
}

在.vstemplate中:

  <WizardExtension>
    <Assembly>Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a55be3860fb01d1</Assembly>
    <FullClassName>Example.NuGetTemplateWizard</FullClassName>
  </WizardExtension>
  <WizardData>
    <packages>
      <package id="Newtonsoft.Json" />
    </packages>
  </WizardData>

另外我不確定通過Task.Run在后台安裝軟件包是否安全,但是這種方式響應速度更快,並且所有異步nuget方法都是內部的(不可用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM