簡體   English   中英

MSBuild BeforeBuild步驟中的Nuget Update Packages.config

[英]Nuget Update Packages.config in MSBuild BeforeBuild Step

我一直在嘗試編寫MsBuild任務,以從Feed網址自動獲取Nuget程序包,並自動更新packages.config以更新至最新版本。

 // ---- Download and install a package at a desired path ----
  var sourceUri = new Uri("FEED URL");

  // ---- Update the ‘packages.config’ file ----
  var packageReferenceFile = new PackageReferenceFile("../../packages.config");
  string packagesPath = "../../packages";
  IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
  PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);

  foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
  {
    if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
    {
      var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));

      if (oldPackage != null)
      {
        packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
      }

      packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));

      // Get the target framework of the current project to add --> targetframework="net452" attribute in the package.config file
      var currentTargetFw = Assembly.GetExecutingAssembly()
        .GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
      var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();

      // Update the packages.config file    
      packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
        SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
        new FrameworkName(targetFrameworkAttribute.FrameworkName));
    }
  }

作為控制台應用程序,它運行良好,並且會自動正確讀取文件並更新必要的參考。

當我嘗試將其作為MsBuild任務運行時,我一直遇到錯誤。

  • 編譯期間發生錯誤。 c:\\ Users \\ user \\ AppData \\ Local \\ Temp \\ dkkg20ya.0.cs(22,11):錯誤CS0246:找不到類型或名稱空間名稱'NuGet'(您是否缺少using指令或程序集引用?)
  • 無法從程序集“ C:\\ Program Files(x86)\\ Microsoft Visual Studio \\ 2017 \\ Enterprise \\ MSBuild \\ 15.0 \\ Bin \\ Microsoft.Build.Tasks.v15.0.dll”中加載任務工廠“ CodeTaskFactory”。 任務工廠必須為“ TaskType”屬性返回一個值。

這是我放入csproj中的代碼(也移至nuget.targets進行測試)

<Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
    <UpdateNugetFiles />
  </Target>
<UsingTask TaskName="UpdateNugetFiles" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll" > 
    <Task>
        <Reference Include="System.Core" />
        <Using Namespace="System" />
        <Using Namespace="System.Linq" />
        <Using Namespace="System.Reflection" />
        <Using Namespace="System.Runtime.Versioning" />
        <Using Namespace="NuGet" />
        <Code Type="Fragment" Language="cs">
            <![CDATA[
            try {
                // ---- Download and install a package at a desired path ----
  var sourceUri = new Uri("FEED URL");

  // ---- Update the ‘packages.config’ file ----
  var packageReferenceFile = new PackageReferenceFile("../../packages.config");
  string packagesPath = "../../packages";
  IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
  PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);

  foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
  {
    if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
    {
      var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));

      if (oldPackage != null)
      {
        packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
      }

      packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));

      // Get the target framework of the current project to add targetframework="net452" attribute in the package.config file
      currentTargetFw = Assembly.GetExecutingAssembly()
        .GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
      var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();

      // Update the packages.config file    
      packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
        SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
        new FrameworkName(targetFrameworkAttribute.FrameworkName));
    }
  }

                return true;
            }
            catch (Exception ex) {
                Log.LogErrorFromException(ex);
                return false;
            }
        ]]>
        </Code>
    </Task>
</UsingTask>

關於如何解決此問題的任何想法似乎都找不到解決方案。 總體而言,在CI構建過程中執行此操作的第一步是使nuget保持最新狀態。

謝謝蒂姆

剛打電話

nuget restore "your_solution.sln"

不要通過用C#代碼編寫輪子來重新發明輪子。

MSBuild BeforeBuild步驟中的Nuget Update Packages.config

不知道您的代碼問題來自哪里。 使用NuGet.exe還原和更新解決方案,而不是嘗試使用C#代碼,可能會更簡單。

因此,您可以在MSBuild BeforeBuild步驟中添加以下nuget命令行

  <Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
    <Exec Command="$(YourNuGetPath)\nuget.exe restore &quot;$(YouSolutionPath)\YourSolution.sln&quot; -PackagesDirectory &quot;$(YouPackagePath)\packages&quot;" />
    <Exec Command="$(YourNuGetPath)\nuget.exe update &quot;$(YouSolutionPath)\YourSolution.sln&quot;" />
  </Target>

注意:如果使用的是Visual Studio,Visual Studio將在構建過程中自動檢查丟失的軟件包並還原它們: Package Restore

希望這可以幫助。

暫無
暫無

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

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