万一有人遇到这种情况,我编写了一个 PowerShell 模块并将其包装在一个 NuGet 包中,用户需要在创建模板时运行该包。该脚本遍历解决方案中的每个 C# 项目,找到其“packages.config”(如果有),然后删除并重新安装其中提到的每个包。
显然,无论是在一般方法方面还是在小错误方面(例如,安装部分中的 nuget 命令不会在全名中有空格的解决方案上运行),都有很大的改进空间,但这是一个开始。
文件NuGet-RestorePackagesInAllProjects.psm1
$NuGetSources = "https://nuget.org/api/v2/;" # put your internal sources here as needed
function NuGet-RestorePackagesInAllProjects {
# get the solution directory
$solutionDir = (get-childitem $dte.Solution.FullName).DirectoryName
# for each C# project in the solution, process packages.config file, if there is one
$dte.Solution.Projects | Where-Object { $_.Type -eq "C#" } | ForEach-Object {
$currentProject = $_
$currentProjectName = $currentProject.ProjectName
$currentProjectDir = (get-childitem $_.FullName).DirectoryName
Write-Host ******* Starting processing $currentProjectName
# get the packages.config file for the current project
$packagesFile = $currentProject.ProjectItems | Where-Object { $_.Name -eq "packages.config" }
# if there's no packages.config, print a message and continue to the next project
if ($packagesFile -eq $null -or $packagesFile.count -gt 1) {
write-host ------- Project $currentProjectName doesn''t have packages.config
return
}
# read the contents of packages.config file and extract the list of packages in it
$fileName = $currentProjectDir + "\packages.config"
[xml]$content = Get-Content $fileName
$packageList = $content.packages.package | % { $_.id }
# for each package in the packages.config, uninstall the package (or simply remove the line from the file, if the uninstall fails)
$packageList | ForEach-Object {
$currentPackage = $_
write-host Uninstalling $currentPackage from $currentProjectName
try {
Uninstall-Package $currentPackage -ProjectName $currentProjectName -RemoveDependencies -Force
}
catch {
write-host '!!!!!!! $_.Exception.Message is' $_.Exception.Message
$node = $content.SelectSingleNode("//package[@id='$currentPackage']")
[Void]$node.ParentNode.RemoveChild($node)
$content.Save($fileName)
}
}
# download each package into the $(SolutionDir)packages folder, and install it into the current project from there
$packageList | ForEach-Object {
$currentPackage = $_
$localPackagesDir = $solutionDir + "\packages"
$cmd = $solutionDir + "\.nuget\nuget.exe install " + $currentPackage + " -Source """ + $NuGetSources + """ -o " + $localPackagesDir
write-host Installing $currentPackage to $currentProjectName
invoke-expression -command $cmd
Install-Package $currentPackage -ProjectName $currentProjectName -Source $localPackagesDir
}
Write-Host ******* Finished processing $currentProjectName
}
}
Export-ModuleMember NuGet-RestorePackagesInAllProjects
文件init.ps1
param($installPath, $toolsPath, $package)
Import-Module (Join-Path $toolsPath NuGet-RestorePackagesInAllProjects.psm1)
Enable-PackageRestore
NuGet-RestorePackagesInAllProjects
包的.nuspec文件
<?xml version="1.0" encoding="utf-16"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>NuGet-RestorePackagesInAllProjects</id>
<version>0.5.0</version>
<title>Custom NuGet Package Restore</title>
<authors>Me (c) 2012</authors>
<owners />
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Restore all packages in a given solution from packages.config in each project. For each packages.config, uninstalls all packages and then re-install them again from the sources specified in the script.</description>
<dependencies>
<dependency id="NuGetPowerTools" />
</dependencies>
</metadata>
<files>
<file src="init.ps1" target="tools\init.ps1" />
<file src="NuGet-RestorePackagesInAllProjects.psm1" target="tools\NuGet-RestorePackagesInAllProjects.psm1" />
</files>
</package>