我一直在尝试编写一个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任务运行时,我一直遇到错误。
这是我在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构建上运行此前一步是为了使nugets保持最新。
由于 添
答案 0 :(得分:0)
致电
nuget restore "your_solution.sln"
不要通过用C#代码编写它来重新发明轮子。
答案 1 :(得分:0)
Nuget在MSBuild BeforeBuild Step中更新Packages.config
不确定代码问题的来源。使用NuGet.exe
来恢复和更新解决方案而不是尝试使用C#代码可能更简单。
因此,您可以在MSBuild BeforeBuild步骤
中添加以下nuget命令行 <Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
<Exec Command="$(YourNuGetPath)\nuget.exe restore "$(YouSolutionPath)\YourSolution.sln" -PackagesDirectory "$(YouPackagePath)\packages"" />
<Exec Command="$(YourNuGetPath)\nuget.exe update "$(YouSolutionPath)\YourSolution.sln"" />
</Target>
注意:如果您使用的是Visual Studio,Visual Studio将在构建期间自动检查缺失的包并将其还原:Package Restore。
希望这会有所帮助。