2

假设我有一个 SP2010 解决方案,它可以做很多事情:创建内容类型、实例化列表、添加事件接收器、Web 等等。现在假设我开发了新的东西:更改一些内容类型,更改一些事件接收器等。现有列表不会受到任何这些影响。我猜这是给定的,但我需要在任何地方应用更改。您将如何很好地处理解决方案更新?

我知道 SharePoint 有一个升级框架(请参阅 SPPersistedUpgradableObject.NeedsUpgrade),但我认为它适用于 SharePoint 产品本身的升级。

那么该怎么办?将当前版本号存储在某个属性包中,连接一个功能激活的事件接收器,在整个世界中递归(网络应用程序、站点、网络、列表......)并升级一切?必须有一些框架来帮助我解决这个问题,如果没有别的,那么至少应该在某个地方显示一个进度条,因为它可能需要 5 分钟或更长时间。欢迎所有想法。

4

1 回答 1

6

这是我的做法:

在部署更新的功能之前,我在 Visual Studio 中打开该功能并更改 Version 属性(当我创建新功能时,我将版本设置为 1.0.0.0)。接下来,我单击 Manifest 按钮,展开 Edit Options 部分,然后输入 UpgradeActions 数据。

以下是我的一项升级功能的略微修改版本:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
 <UpgradeActions>
  <VersionRange BeginVersion="1.0.0.0" EndVersion="1.1.0.0">
   <CustomUpgradeAction Name="UpgradeTo1v1" />
  </VersionRange>
  <VersionRange BeginVersion="1.1.0.0" EndVersion="1.3.0.0">
   <CustomUpgradeAction Name="UpgradeTo1v3" />
  </VersionRange>
  <VersionRange BeginVersion="1.3.0.0" EndVersion="1.4.0.0">
   <CustomUpgradeAction Name="UpgradeTo1v4">
    <Parameters>
     <Parameter Name="OptionalParameter">Values go here</Parameter>
    </Parameters>
   </CustomUpgradeAction>
  </VersionRange>
 </UpgradeActions>
</Feature>

然后我添加或修改我的特征接收器的 FeatureUpgrading 方法:

[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
public override void FeatureUpgrading(
    SPFeatureReceiverProperties properties, 
    string upgradeActionName, 
    System.Collections.Generic.IDictionary<string, string> parameters)
{
    SPSite site = properties.Feature.Parent as SPSite;
    SPWeb web = site.RootWeb;
    switch (upgradeActionName)
    {
        case "UpgradeTo1v1":
            UpgradeTo1v1(site, properties, parameters);
            break;
        case "UpgradeTo1v3":
            UpgradeTo1v3(site, properties, parameters);
            break;
        case "UpgradeTo1v4":
            UpgradeTo1v4(site, properties, parameters);
            break;
    }
}

我的私有升级方法以编程方式进行任何在部署更新的解决方案包时无法自动实现的更改。我使用以下 PowerShell 脚本部署解决方案包:

Write-Host "Upgrading solution: $SolutionPackageName" -NoNewline
Update-SPSolution -Identity $SolutionPackageName -LiteralPath $SolutionPackagePath -GACDeployment -Confirm:$false -Force
while ($Solution.JobExists)
{
    Start-Sleep -s 2
}
Write-Host " - Done."

if ($UpdateFeatureGuids -ne $null)
{
    foreach ($site in Get-SPSite -Limit All) 
    {
        $UpdateFeatureGuids | % { $site.QueryFeatures([Guid]$_, [bool]$true) } | % { 
            $definitionId = $_.DefinitionId
            $parentUrl = $_.Parent.Url
            Write-Host "Upgrading feature: $definitionId $parentUrl"
            $_.Upgrade([bool]$false) | % { 
                if ($_ -ne $null)
                {
                    Format-List -InputObject $_ -Property Message, InnerException -Force 
                }
            }
            Write-Host "Upgrading feature: $definitionId $parentUrl - Done."
        }
        $site.Dispose()
    }
}

我真的希望Update-SPSolution有一个标志可以让您升级所有活动功能。我还没有遇到需要更新功能但不希望应用程序化升级的案例。因此,PowerShell 代码的其余部分为我完成了这项工作,方法是浏览所有网站集,根据预定义的列表查找所有需要升级的功能,然后在显示发生的任何错误的同时升级每个网站上的功能。

请注意,Update-SPSolution仅刷新现有文件。如果您已将新文件添加到解决方案包,它们将被忽略并且不会被部署。我希望功能的版本历史和升级能力不会因撤回/部署而无效,但我从未尝试过。通常,如果我需要添加新文件,我会创建一个新的解决方案包。

于 2012-07-09T20:26:20.570 回答