有没有一种简单的方法可以从本地项目引用切换到nuget包?

时间:2014-03-19 21:08:11

标签: .net nuget package-managers

在我目前的项目中,我们有几个由+20个不同系统使用的独立库。

最近我们决定使用NuGet开始管理我们的库...我们已经在内部NuGet服务器上发布了所有库作为nuget包,现在我们将开始迁移我们的+20应用程序以将这些库用作nuget包而不是本地项目引用。

是否有简单/自动的方式进行这些更改?

2 个答案:

答案 0 :(得分:2)

在项目中运行包的Install-Package命令,引用将更新到nuget包目录(或任何你配置的目录)。

如果您的软件包不仅仅是添加一个简单的引用(例如,ASP.NET MVC软件包修改了Web.config文件),那么您将有一些撤消操作,但它通常是一种相对轻松的更新方式.csproj引用

答案 1 :(得分:1)

我曾经写过一个PowerShell脚本来做你想做的事(我想)。可能是一个适合你的地方。必须从Visual Studio中的PowerShell控制台执行此操作。这两个参数是项目名称和相应的包名称。

param (
    [parameter(Mandatory = $true)] [string] $referencedProjectName,
    [parameter(Mandatory = $true)] [string] $packageName
)



function Backup-File
{
    param ([parameter(Mandatory = $true)][string] $file)

    try
    {
        if (!(Test-Path $file))
            { throw "Could not find file $file" }

        $backup = $file + ".bak"

        if (Test-Path $backup)
            { Remove-Item $backup -Force }

        Write-Host "Backing-up $file"

        Copy-Item -Path $file -Destination $backup
    }

    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }
}



function Solution-Strip-Project-Reference
{
    param (
        [parameter(Mandatory = $true)] [string] $solutionFile,
        [parameter(Mandatory = $true)] [string] $referencedProjectName
    )

    try
    {
        $regEx = '^Project\("\{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC\}"\)\s*=\s*"' + $referencedProjectName + '"'

        $content = Get-Content $solutionFile

        $newContent = @()

        for ($i = 0; $i -lt $content.Count; ++$i)
        {
            $line = $content[$i]

            if ($line -notmatch $regEx)
                { $newContent += $line; continue }

            do { ++$i; $line = $content[$i] } while ($line -notmatch "^EndProject$")
        }

        if ($newContent.Count -ne $content.Count)
        {
            Write-Host "Stripping project $referencedProjectName from solution $solutionFile"
            $newContent | Set-Content $solutionFile
        }
    }

    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }
}




function Solution-Get-Project-List
{
    param (
        [parameter(Mandatory = $true)][string] $solutionFile
    )

    $projects = @()

    try
    {
        if (!(Test-Path $solutionFile))
            { throw "Could not find file $solutionFile" }

        $regEx = '^Project\("\{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC\}"\)\s*=\s*"(?<name>[^"]*)",\s*"(?<path>[^"]*)",\s*"(?<guid>[^"]*)"'

        $content = Get-Content $solutionFile

        for ($i = 0; $i -lt $content.Count; ++$i)
        {
            $line = $content[$i]

            if ($line -match $regEx)
            { 
                $name = $Matches['name']
                $projectPath = Resolve-Path $Matches['path'] -ErrorAction SilentlyContinue

                if ($projectPath -eq $null -or !(Test-Path $projectPath))
                    { continue }

                $guid = $Matches['guid']
                $xml = [XML](Get-Content $projectPath)


                $project = New-Object Object |
                    Add-Member -MemberType NoteProperty -Name "Name" -Value $name -PassThru |
                    Add-Member -MemberType NoteProperty -Name "Path" -Value $projectPath -PassThru |
                    Add-Member -MemberType NoteProperty -Name "Guid" -Value $guid -PassThru |
                    Add-Member -MemberType NoteProperty -Name "XML"  -Value $xml -PassThru

                $projects += $project
            }
        }
    }

    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }

    return $projects
}



function Project-Remove-Reference
{
    param (
        [parameter(Mandatory = $true)][object] $project,
        [parameter(Mandatory = $true)][object] $referencedProject
    )

    try
    {
        $nm = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $project.XML.NameTable
        $nm.AddNamespace('x', 'http://schemas.microsoft.com/developer/msbuild/2003')
        $projectNode = $project.XML.SelectSingleNode("/x:Project/x:ItemGroup/x:ProjectReference/x:Project[.='" + $referencedProject.Guid + "']", $nm)

        if ($projectNode)
        {
            $projectReferenceNode = $projectNode.ParentNode
            $itemGroupNode = $projectReferenceNode.ParentNode
            $itemGroupNode.RemoveChild($projectReferenceNode) | Out-Null
            $project.XML.Save($project.Path) | Out-Null
        }
    }

    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }
}



function Project-Install-Nuget-Package
{
    param (
        [parameter(Mandatory = $true)][object] $project,
        [parameter(Mandatory = $true)][string] $packageName
    )

    try
    {
        Install-Package -Id $packageName -ProjectName $project.Path
    }

    catch 
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }   
}



function Project-Contains-Reference
{
    param (
        [parameter(Mandatory = $true)][object] $project,
        [parameter(Mandatory = $true)][object] $referencedProject
    )

    $retVal = $null

    try
    {
        $nm = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $project.XML.NameTable
        $nm.AddNamespace('x', 'http://schemas.microsoft.com/developer/msbuild/2003')
        $node = $project.XML.SelectSingleNode("/x:Project/x:ItemGroup/x:ProjectReference/x:Name[.='" + $referencedProject.Name + "']", $nm)
        $retVal = $node -ne $null
    }

    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_"
    }

    return $retVal
}



try
{
    $Error.Clear()

    Push-Location

    if (!(Get-Package $packageName -ListAvailable))
        { throw "Could not find package $packageName" }

    $path = Split-Path (Resolve-Path $MyInvocation.InvocationName) -Parent

    $solutions = @(Get-ChildItem $path -Filter "*.sln" -Recurse)

    $solutions | foreach { 
        $solution = $_

        cd (Split-Path $solution.FullName -parent)

        $projectList = Solution-Get-Project-List $solution
        $referencedProject = $projectList | where { $_.Name -eq $referencedProjectName }

        if ($referencedProject -ne $null)
        {
            Backup-File $solution
            Solution-Strip-Project-Reference $solution $referencedProjectName

            foreach ($project in $projectList | where { Project-Contains-Reference $_ $referencedProject } )
            {
                Backup-File $project.Path
                Project-Remove-Reference $project $referencedProject
                Project-Install-Nuget-Package $project $packageName
            }
        }
    }
}

catch
{
    Write-Host "$($MyInvocation.InvocationName): $_"
}

finally
{
    Pop-Location
}