【问题标题】:Programatically creating a NuGet package for a local repository以编程方式为本地存储库创建 NuGet 包
【发布时间】:2015-04-11 03:07:20
【问题描述】:

我正在编写一个控制台应用程序来创建 NuGet 包(使用 Nuget.Core 库),这些包将托管在我们的内部服务器上以部署到我们的应用程序中。当我们使用 NuGet 包资源管理器手动创建包时,这一切都很好,但我们现在需要自动化这个过程。

我将以下代码拼凑在一起以自动构建包,但在builder.Populate(packageMetadata); 行出现错误

错误是:

Value cannot be null.

Parameter name: source

这是堆栈跟踪:

at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at NuGet.PackageBuilder.Populate(ManifestMetadata manifestMetadata)
at BuildPackage.Create(String packageName, String path, String description) in c:\Source Code\Visual Studio Projects\Tools\Console Applications\NuGet Package Builder\BuildPackage.cs:line 134

我查看了 NuGet 的源代码(请参阅 here),但我不知道是什么原因造成的。

关于以下代码的几点说明:

  • 前两个区域只是为了弄清楚新包的版本号,你可以忽略它们
  • ReferencePaths.NuGetPackages 是我们本地 NuGet 存储库路径的静态字符串
  • 此代码使用提供的 packageName 和路径获取已构建的 DLL 和 PDB 文件

代码如下:

class BuildPackage
{
    public static void Create(string packageName, string path, string description)
    {
        try
        {
            #region Get the current package version

            int major = 0;
            int minor = 0;
            int packageNo = 0;
            List<string> files = Directory.EnumerateFiles(ReferencePaths.NuGetPackages, packageName + "*").ToList();

            if (files.Count > 0)
            {
                foreach (string file in files)
                {
                    string[] versions = file.Replace(ReferencePaths.NuGetPackages, "").Replace(packageName + ".", "").Replace(".nupkg", "").Split('.');
                    int newMajor = Convert.ToInt32(versions[0]);
                    int newMinor = Convert.ToInt32(versions[1]);
                    int newPackageNo = Convert.ToInt32(versions[2]);

                    // Figure out if this is the latest package
                    if (newMajor > major ||
                        (newMajor == major && newMinor > minor) ||
                        (newMajor == major && newMinor == minor && newPackageNo > packageNo))
                    {
                        major = newMajor;
                        minor = newMinor;
                        packageNo = newPackageNo;
                    }
                }
            }

            #endregion Get the current package version

            #region Get the new assembly version

            FileVersionInfo version = FileVersionInfo.GetVersionInfo(path + packageName + ".dll");

            if (version.FileMajorPart > major ||
                (version.FileMajorPart == major && version.FileMinorPart > minor))
            {
                major = version.FileMajorPart;
                minor = version.FileMinorPart;
                packageNo = 0;
            }
            else
            {
                while (File.Exists(ReferencePaths.NuGetPackages + packageName + "." + major.ToString() + "." + minor.ToString() + "." + packageNo.ToString() + ".nupkg"))
                {
                    packageNo++;
                }
            }

            #endregion Get the new assembly version

            #region Create the package

            string packageVersion = major.ToString() + "." + minor.ToString() + "." + packageNo.ToString();
            string newPackageName = packageName + "." + packageVersion + ".nupkg";
            ManifestMetadata packageMetadata = new ManifestMetadata();
            packageMetadata.Id = packageName;
            packageMetadata.Version = packageVersion;
            packageMetadata.Authors = "Test";
            packageMetadata.Description = description;

            List<ManifestFile> manifestFiles = new List<ManifestFile>();
            ManifestFile dllFile = new ManifestFile();
            dllFile.Source = packageName + ".dll";
            dllFile.Target = @"lib\" + packageName + ".dll";
            manifestFiles.Add(dllFile);
            ManifestFile pdbFile = new ManifestFile();
            pdbFile.Source = packageName + ".pdb";
            pdbFile.Target = @"lib\" + packageName + ".pdb";
            manifestFiles.Add(pdbFile); 

            PackageBuilder builder = new PackageBuilder();
            builder.PopulateFiles(path, manifestFiles);
            builder.Populate(packageMetadata);
            using (FileStream stream = File.Open(ReferencePaths.NuGetPackages + newPackageName, FileMode.OpenOrCreate))
            {
                builder.Save(stream);
            }

            #endregion Create the package

            Console.WriteLine("New package created: " + newPackageName);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

有谁知道可能出了什么问题?我需要 ManifestMetadata 中的更多信息吗?我尝试填写所有我能想到的属性,但没有帮助。

【问题讨论】:

  • 显示完整的堆栈跟踪。此外,如果您需要方法内部的区域,您可能希望将方法拆分为较小的方法。
  • 我已将堆栈跟踪添加到问题中。不确定区域的事情 - 如果代码没有在任何地方重用,似乎没有必要将其提取到方法中,但这是另一个话题!
  • 任何使用最新版本 NuGet.Core v2.8.5 的最终解决方案都可以自动执行此过程?
  • 我不确定我是否理解您的问题;上面的代码适用于 NuGet.Core v2.8.5 - 如下面的答案所示。它对你有用吗?

标签: c# c#-4.0 nuget


【解决方案1】:

好吧,我尝试了几种不同的方法来做同样的事情,但都没有奏效。所以我注意到http://nuget.codeplex.com/SourceControl 上的代码版本都是 v2.0 以上,并决定检查我引用的 DLL(这是股票 .NET 4.0 或 4.5 版本),我注意到我的 NuGet.Core 参考是针对版本的1.6.3.

所以,我使用 NuGet 包管理器来获取最新版本的 NuGet.Core(在撰写本文时是 v2.8.5),现在上面的确切代码可以正常工作了! *

Alanis Morissette 可能会说这很讽刺。

  • 我确实必须在保存前更改 File.Open,因为我错过了文件名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-29
    • 2011-02-23
    • 2016-03-13
    • 2014-10-22
    • 1970-01-01
    • 2021-02-18
    • 2018-02-09
    • 2014-06-29
    相关资源
    最近更新 更多