Aptillon Blog

Integrating post-processors in SharePoint builds

Posted by Maurice Prather

Have you ever needed to process an assembly prior to having it packaged up for deployment?  A classic example of this requirement is using an obfuscator or signing/watermarking tool.

Prior to the introduction of the VS2010 SharePoint tools, the general advice was to use AfterBuild (reference How to: Extend the Visual Studio Build Process). Unfortunately, this doesn't really work when dealing with solution packages built in VS2010.

The reason is pretty simple – AfterBuild is too late.  You can run your assemblies through the tooling process, but the modified assemblies won’t be a part of your solution package.  The packaging step picks up the assemblies before AfterBuild kicks off.

How about AfterCompile? This window of opportunity for post-processing your assembly is ok, but not entirely what you want to use.  You will get your processed assembly into the solution package; however, since the tool will modify your assembly, in the long run you will be wasting a lot of time and cpu as AfterCompile will be called multiple times.  On a fast running process, you may never even notice this is happening.  On a long running process, your mods will trigger multiple calls to compile and the time to completion will literally get out of hand.

The right solution?  Override AfterLayout.

This target is new target that is listed as a dependency by the CreatePackage target found in Microsoft.VisualStudio.SharePoint.targets.




All you need to do is open up your project file and add a definition for AfterLayout as shown below:




As you can see, AfterLayout is the perfect solution!

The really nice thing is you can use conditional expressions to define when to run the post-processing tool.  In the example above, the tool is run only when working with Release builds.

The build process will go through and copy all the files into the pkg folder.  AfterLayout is called once all the files are dropped into the folder, but before they are bundled up into the wsp.  Your post-processing tool can then reference the built assembly from the pkg folder.




Ta-da!  Done.  Your post-processing tool will run when you need it w/o taking the multi-run penalty of using AfterCompile

Just to give you an example of how efficient AfterLayout is compared to AfterCompile, we recently reduced our build times on one of projects from roughly 3 hours to under 32 minutes.  Old habits of defaulting to AfterCompile basically cost us a lot of time early on in our dev cycle... I can’t tell you how nice it was to get builds back down to normal times.  :)

Happy coding!


Tagged as: ,
To post a comment, view the original posting.

SharePoint 2010 SP1 Public API Changes

Posted by Gary Lapointe

I recently published a post detailing the SharePoint 2010 SP1 PowerShell changes and, in that post, I mentioned that I was probably going to detail the API changes. Well, here they are. Note that the list below is not a comprehensive one in that I’m not showing every assembly (I do have the changes for every assembly but frankly I just got tired of translating the results into a readable format so I kept it to the more prominent assemblies (or at least the ones that I just happened to have done at the time)). In reviewing the list you see that there’s honestly not a whole lot of noteworthy changes, but that’s okay as part of my reasoning for doing this was to discover whether there were any (don’t get me wrong, there are some, in fact, for me there’s 1 very big one that made this whole exercise worth it – I’ll let you figure out which one that is). If you find any I missed please add a comment so that others can see it as well.

  • Microsoft.SharePoint.dll
    • Microsoft.SharePoint.SPRecycleBinItemType
      • New enum value:
        • Web
    • Microsoft.SharePoint.SPWeb
      • New method:
        • public void Recycle()
    • Microsoft.SharePoint.Strings
      • New constants:
        • public const string CannotRecycleRootWeb
        • public const string HealthRule_Explanation_BcsShimsAreEnabled
        • public const string HealthRule_Remedy_BcsShimsAreEnabled
        • public const string RecycleBinWebMissingContainerError
        • public const string SPStorageMetricsProcessingJobDescription
        • public const string SPUsageUserCodeRequestsDescription
        • public const string SPUsageUserCodeRequestsMonitoredDataDescription
        • public const string SiteAlreadyExists
        • public const string StorageMetricsDBObjectsNotFound
        • public const string StorageMetricsFreshnessWarning
        • public const string StorageMetricsNotAvailable
        • public const string TimerJobTitleStorageMetricsProcessing
    • Microsoft.SharePoint.Administration.SPAce<T>
      • New properties:
        • public Byte[] BinaryId() { get; }
        • public Microsoft.SharePoint.Administration.SPIdentifierType BinaryIdType() { get; }
    • Microsoft.SharePoint.Administration.SPAcl<T>
      • New method:
        • public SPAce<T> Add(string principalName, string displayName, SPIdentifierType identifierType, byte[] identifier, T grantRightsMask, T denyRightsMask)
    • Microsoft.SharePoint.Administration.SPContentDatabase
      • New methods:
        • public Microsoft.SharePoint.Administration.SPDeletedSite GetDeletedSite(System.Guid id)
        • public void Move(SPContentDatabase destinationDb, List<SPSite> sitesToMove, Dictionary<string, string> rbsProviderMap, out Dictionary<SPSite, string> failedSites)
    • Microsoft.SharePoint.Administration.SPContentDatabaseCollection
      • New method:
        • public SPContentDatabase Add(string strDatabaseServer, string strDatabaseName, string strDatabaseUsername, string strDatabasePassword, int warningSiteCount, int maximumSiteCount, int status, bool flushChangeLog, bool changeSyncKnowledge)
    • Microsoft.SharePoint.Administration.SPDatabase
      • New method:
        • public void ChangeDatabaseInstance(string databaseServiceInstance)
    • Microsoft.SharePoint.Administration.SPIncomingEmailService
      • New property:
        • public int RetryDeliveryInterval { get; set; }
    • Microsoft.SharePoint.Administration.SPPolicy
      • New method:
        • protected Void OnDeserialization()
    • Microsoft.SharePoint.Administration.SPSiteLookupProvider
      • Changed method (breaking change!)
        • public Void RenameHostHeaderSite(Guid siteId, string newHostHeader) => public Void RenameHostHeaderSite(Guid siteId, Uri newHostHeaderSiteUri)
    • Microsoft.SharePoint.Administration.SPUsageApplication
      • New property:
        • public int UsageInsertionTimeOut { get; set; }
    • Microsoft.SharePoint.Administration.SPUserCodeExecutionTier
      • New property:
        • public int PriorityPerProcess { get; set; }
    • Microsoft.SharePoint.Administration.SPWebApplication
      • New properties:
        • public int StorageMetricsProcessingDuration { get; set; }
        • public uint MaxDiscussionBoardItemsForSiteDataFolderQuery { get; set; }
        • public uint? UserDefinedWorkflowMaximumComplexity { get; set; }
      • New methods:
        • public SPDeletedSiteCollection GetDeletedSites()
        • public SPDeletedSiteCollection GetDeletedSites(SPDeletedSiteQuery query)
        • public SPDeletedSiteCollection GetDeletedSites(Guid siteId)
        • public SPDeletedSiteCollection GetDeletedSites(string sitePath)
        • public void MigrateUsers(IMigrateUserCallback callback)
    • Microsoft.SharePoint.Administration.SPWebService
      • New properties:
        • public int ImagingDownloadSizeLimit { get; set; }
        • public bool EnableHostHeaderSiteBasedSchemeSelection { get; set; }
    • Microsoft.SharePoint.Administration.Claims.SPActiveDirectoryClaimProvider
      • New method:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
    • Microsoft.SharePoint.Administration.Claims.SPAllUserClaimProvider
      • New method:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
    • Microsoft.SharePoint.Administration.Claims.SPClaimHierarchyProvider
      • New methods:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
        • public string GetLocalizedDisplayName()
    • Microsoft.SharePoint.Administration.Claims.SPClaimProvider
      • New property:
        • public virtual bool SupportsUserKey { get; }
      • New methods:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
        • public string GetLocalizedDisplayName()
        • public SPClaim UserKeyForEntity(SPClaim entity)
        • public virtual string GetClaimTypeForUserKey()
        • protected virtual SPClaim GetUserKeyForEntity(SPClaim entity)
    • Microsoft.SharePoint.Administration.Claims.SPClaimProviderDefinition
      • New property:
        • public bool IsVisible { get; set; }
    • Microsoft.SharePoint.Administration.Claims.SPClaimProviderOperationOptions
      • New enum value:
        • OverrideVisibleFlag
    • Microsoft.SharePoint.Administration.Claims.SPFormsClaimProvider
      • New method:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
    • Microsoft.SharePoint.Administration.Claims.SPSystemClaimProvider
      • New method:
        • protected override void FillDefaultLocalizedDisplayName(CultureInfo culture, out string localizedName)
    • Microsoft.SharePoint.BusinessData.Administration.LobSystem
      • New static method:
        • public static LobSystem MergeXml(string xml, out string[] errors, PackageContents packageContents, AdministrationMetadataCatalog metadataCatalog, string settingId)
    • Microsoft.SharePoint.BusinessData.Administration.TypeDescriptor
      • New static method:
        • public static TypeDescriptor MergeXml(string xml, out string[] errors, PackageContents packageContents, Parameter parameter, TypeDescriptor parent, string settingId)
    • Microsoft.SharePoint.BusinessData.SharedService.BdcServiceApplicationProxy
      • New methods:
        • public bool IsSystemTypeEnabled(SystemType systemType)
        • public void EnableSystemType(SystemType systemType, bool value)
    • Microsoft.SharePoint.JSGrid.GridSerializer
      • New method:
        • public void ApplyPostViewIncrementalInsertsAndDeletes(IEnumerable changes, Func> fnGetDefaultValuesForPostViewInserts)
    • Microsoft.SharePoint.JSGrid.HierarchyNode
      • New property:
        • public HierarchyNode Parent { get; set; }
    • Microsoft.SharePoint.Utilities.SPUtility
      • New static method:
        • public static Stream ExecuteCellStorageBinaryRequest(SPFile spfile, Stream request, bool coalesce, ref Guid partitionID, string userName, bool coauthVersioning, string etagMatching, bool fExpectNoFileExists, string contentChangeUnit, string clientFileID, string bypassSchemaID, long nLockType, string lockID, long nTimeout, bool createParentFolder, out string etagReturn, out bool allRequestSucceeded, out int coalesceHRESULT, out string coalesceErrorMessage, out bool containHotboxData, out bool haveOnlyDemotionChanges, ref int binaryReqCountQuota)
    • Microsoft.SharePoint.WebPartPages.ListFormWebPart
      • New method:
        • public bool ShouldSerializeTemplateName()
    • New classes:
      • Microsoft.SharePoint.Administration.SPDeletedSite
      • Microsoft.SharePoint.Administration.SPDeletedSiteCollection
      • Microsoft.SharePoint.Administration.SPDeletedSiteLookupInfo
      • Microsoft.SharePoint.Administration.SPDeletedSiteQuery
      • Microsoft.SharePoint.Administration.SPUsageUserCodeRequests
      • Microsoft.SharePoint.Administration.SPUsageUserCodeRequestsEntry
      • Microsoft.SharePoint.Administration.SPUsageUserCodeRequestsMonitoredData
      • Microsoft.SharePoint.Administration.SPUsageUserCodeRequestsMonitoredDataEntry
      • Microsoft.SharePoint.Administration.Health.SPHealthAnalysisRuleInstance
      • Microsoft.SharePoint.WebControls.IEVersionMetaTag
    • New enum types:
      • Microsoft.SharePoint.Administration.SPIdentifierType
    • New interfaces:
      • Microsoft.SharePoint.Administration.IMigrateUserCallback
      • Microsoft.SharePoint.Administration.ISPSiteLookupProviderRecycleBin
  • Microsoft.SharePoint.Publishing.dll
    • Microsoft.SharePoint.Publishing.Internal.CodeBehind
      • New property:
        • protected bool IsCurrentUserSiteAdmin { get; }
    • Microsoft.SharePoint.Publishing.WebControls.SpellCheckV4Action
      • New method:
        • protected bool ShouldRenderWithoutTabs()
    • Microsoft.SharePoint.Publishing.WebControls.EditingMenuActions.ConsoleAction
      • New method:
        • protected bool ShouldRenderWithoutTabs()
  • Microsoft.SharePoint.Taxonomy.dll
    • Microsoft.SharePoint.Taxonomy.TermStore
      • New method:
        • public Group GetSiteCollectionGroup(SPSite currentSite)
  • Microsoft.SharePoint.Portal.dll
    • Microsoft.Office.Server.UserProfiles.UserProfileService
      • New methods:
        • public void AddLeader(string accountName)
        • public Leader[] GetLeaders()
        • public void RemoveLeader(string accountName)
  • Microsoft.Office.Server.UserProfiles.dll
    • Microsoft.Office.Server.SocialData.PluggableSocialSecurityTrimmerManager
      • New methods:
        • public static string[] GetUrlFoldersRequiringTrim(SPServiceContext serviceContext)
        • public static string[] GetUrlFoldersToAlwaysAllow(SPServiceContext serviceContext)
        • public static void SetTrimmerSettings(SPServiceContext serviceContext, bool enableTrimming)
        • public static void SetTrimmerSettings(SPServiceContext serviceContext, string[] urlFoldersRequiringTrim, string[] urlFoldersToAlwaysAllow)
    • Microsoft.Office.Server.UserProfiles.BusinessDataCatalogConnection
      • New method:
        • public void Delete()
    • Microsoft.Office.Server.UserProfiles.ConnectionManager
      • New method:
        • public DirectoryServiceConnection AddActiveDirectoryConnection(ConnectionType type, string displayName, string server, bool useSSL, string accountDomain, string accountUsername, SecureString accountPassword, List<DirectoryServiceNamingContext> namingContexts, string spsClaimProviderTypeValue, string spsClaimProviderIdValue, string adClaimIDMapAttribute)
    • Microsoft.Office.Server.UserProfiles.UserProfileManager
      • New methods:
        • public void AddLeader(string accountName)
        • public Leader[] GetLeaders()
        • public void RemoveLeader(string accountName)
    • New classes:
      • Microsoft.Office.Server.UserProfiles.Leader
  • Microsoft.Office.Server.Search.dll
    • Microsoft.Office.Server.Search.Administration.CrawlTopologyState
      • New enum values:
        • ActiveToBeRemoved
        • DeactivatingToBeRemoved
    • Microsoft.Office.Server.Search.Administration.SearchServiceApplication
      • New property:
        • public uint CrawlLogCleanupIntervalInDays { get; set; }
    • Microsoft.Office.Server.Search.Administration.SearchServiceApplicationProxy
      • New property:
        • public LocationConfigurationCollection LocationConfigurations { get; }
    • Microsoft.Office.Server.Search.Query.QueryInfo
      • New property:
        • public string CorrelationId { get; set; }
    • Microsoft.Office.Server.Search.Query.QueryManager
      • New method:
        • public System.Xml.XmlDocument GetResults()
  • Microsoft.SharePoint.PowerShell.dll
    • New classes:
      • Microsoft.SharePoint.PowerShell.SPDeletedSitePipeBind
      • Microsoft.SharePoint.PowerShell.SPHealthAnalysisRuleInstancePipeBind

View the original post on Gary’s personal blog for comments and all related downloads: SharePoint 2010 SP1 Public API Changes