I have a custom content type which I am deploying to a Site collection in which content type hub is configured. To use the content types in different site collection after the content type is deployed we have to perform three steps:
1) Publish the content type
2) Run the Content Type Hub timer job
3) Run the Content Type Subscriber timer job.
I found this blog here, which is doing the same in feature activation.
My Code
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//bool remoteAdministratorAccessDenied = SPWebService.ContentService.RemoteAdministratorAccessDenied;
try
{
//SPWeb spWeb = properties.Feature.Parent as SPWeb;
//SPSite spSite = spWeb.Site;
string contentTypeHubSiteURL = string.Empty;
//System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("/", spSite.WebApplication.Name);
// App settings are retrieved this way
if (properties.Feature.Properties["CTHubUrl"] != null)
{
contentTypeHubSiteURL = Convert.ToString(properties.Feature.Properties["CTHubUrl"].Value);
}
else
{
contentTypeHubSiteURL = "hardcoded url";
}
if (!string.IsNullOrEmpty(contentTypeHubSiteURL))
{
using (SPSite siteCtHub = new SPSite(contentTypeHubSiteURL))
{
using (SPWeb webCtHub = siteCtHub.RootWeb)
{
if (ContentTypePublisher.IsContentTypeSharingEnabled(siteCtHub))
{
ContentTypePublisher ctPublisher = new ContentTypePublisher(siteCtHub);
IEnumerable<SPContentType> spContentTypes =
webCtHub.AvailableContentTypes
.Cast<SPContentType>().Where(ct => ct.Group == "My group");
foreach (SPContentType spContentType in spContentTypes)
{
ctPublisher.Publish(spContentType);
Thread.Sleep(100);
}
}
}
}
using (SPSite siteCtHub = new SPSite(contentTypeHubSiteURL))
{
using (SPWeb webCtHub = siteCtHub.RootWeb)
{
//SPWebService.ContentService.RemoteAdministratorAccessDenied = false;
SPWebApplication spWebApp = siteCtHub.WebApplication;
SPService saMMS = spWebApp.Farm.Services.Cast<SPService>()
.FirstOrDefault(s => s.TypeName == "Managed Metadata Web Service");
SPJobDefinition ctHubTimerJob = null;
//Run the Content Type Hub Job
//This timer job is associated with the MMS service application
ctHubTimerJob = saMMS.JobDefinitions.Cast<SPJobDefinition>()
.FirstOrDefault(jd => jd.Title == "Content Type Hub");
if (ctHubTimerJob == null)
{
saMMS = spWebApp.Farm.Services.Cast<SPService>()
.FirstOrDefault(s => s.TypeName ==
"Microsoft SharePoint Foundation Timer");
ctHubTimerJob = saMMS.JobDefinitions.Cast<SPJobDefinition>()
.FirstOrDefault(jd => jd.Title ==
"Content Type Hub");
}
DateTime startTime = DateTime.Now.ToUniversalTime();
ctHubTimerJob.RunNow();
while ((from SPJobHistory j in saMMS.JobHistoryEntries
where j.JobDefinitionId ==
ctHubTimerJob.Id && j.StartTime >
startTime
select j).Any() == false)
{
Thread.Sleep(100);
}
//Run the Content Type Subscriber Job
//This timer job is associated with the subscriber's web application
SPJobDefinition ctHubSubTimerJob = spWebApp.JobDefinitions.Cast<SPJobDefinition>()
.FirstOrDefault(jd => jd.Title == "Content Type Subscriber");
startTime = new DateTime();
startTime = DateTime.Now.ToUniversalTime();
ctHubSubTimerJob.RunNow();
while ((from SPJobHistory j in spWebApp.JobHistoryEntries
where j.JobDefinitionId ==
ctHubSubTimerJob.Id && j.StartTime >
startTime
select j).Any() == false)
{
Thread.Sleep(100);
}
}
}
}
}
catch (Exception)
{
throw;
}
finally
{
//SPWebService.ContentService.RemoteAdministratorAccessDenied = remoteAdministratorAccessDenied;
}
}
My feature is scoped at web level(also tried with SiteCollection level), but getting access denied error in this line
ctHubSubTimerJob.RunNow();
Also tried RunwithElevatedPrivelege, anyways I am having farm administrator privilege.
Am I doing something wrong? Are there any workaround?