Starting custom Sharepoint timer programatically II

A few days ago I wrote about How to start custom SharePoint timer programatically. In this post, I talked about the problems that we could find before starting a Sharepoint timer programatically.

Today, I want to expand on this topic with another post. First, I want to talk about instruccions that we need for starting the timer.

Below, there is a piece of code to start the timer programatically.

public staticvoid StartJob(thisSPSite Site, string JobName, Dictionary<string, object> properties)

{

SPSecurity.RunWithElevatedPrivileges(delegate()

{

   using (SPSite elevatedSite = newSPSite(Site.ID))

{

     SPSite site = elevatedSite;

     SPJobDefinition myjob = FindJob(elevatedSite,JobName);

foreach(string k in properties.Keys)

{

myjob.Properties[k] = properties[k];

}

myjob.RunNow();

}

});

}

It’s nothing special. Maybe the way that we can find the timer job instance is a bit important to know how to avoid problems.

public staticSPJobDefinition FindJob(thisSPSite elevatedSite, string JobName)

{

 SPJobDefinition myjob = null;

 foreach (SPJobDefinition job in elevatedSite.WebApplication.JobDefinitions)

{

   if (job.Name.Equals(JobName, StringComparison.OrdinalIgnoreCase))

{

myjob = job;

      break;

}

}

 return myjob;

}

In timer job, also, there is a way to bypass parameters by properties. This properties could be persistent or not, it depends on how you declare it in timer job.

It’s very common that a timer job is instantiate in site level and we need to execute to web level. This kind of problem can be resolved using properties. You can see an example on this lines.

Dictionary<string, object> properties = newDictionary<string, object>();

properties.Add(“isManual”, true);

properties.Add(“force-web-id”, SPContext.Current.Web.ID);

SPContext.Current.Web.Site.StartJob(JobDefinition.Name, properties);

And what about its status? Reading the status of timer job could be a little complicated. You need to reiterate the status list and get the last log written by the job. For example if job is running:

public static bool IsJobRunning(thisSPSite Site, string JobName)

{

 bool isrunning = false;

 InformationJob ijob = newInformationJob();

 SPSecurity.RunWithElevatedPrivileges(delegate()

{

  using (SPSite elevatedSite = newSPSite(Site.ID))

{

    SPJobDefinition myjob = FindJob(elevatedSite,JobName);

    if (myjob.IsDisabled)

{

isrunning = false;

}

    else

{

      try

{

         var e = myjob.HistoryEntries.OrderByDescending(i => i.StartTime).First();

isrunning = e.Status ==SPRunningJobStatus.Initialized;

}

      catch

{

isrunning =false;

}

}

}

});

 return isrunning;

}

I recommend creating another list to register your own log and to set one mark for knowing when it begins and another for knowing when it finishes. Here you can see an example of the list:

logjob

So, in this way, you only need to read your own log and find the mark that tells you what the status of your job is. For example if  job is finished:

private bool IsJobFinished()

{

  bool isFinished = false;

InformationJob ijob = newInformationJob();

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using (SPSite elevatedSite = newSPSite(SPContext.Current.Site.ID))

{

SPJobDefinition myjob = FindJob(elevatedSite);

if (myjob.IsDisabled)

{

isFinished =false;

}

     else

{

        try

{

          SPList listLog = SPContext.Current.Web.GetListByUrl(JobDefinition.LogListUrl);

          if (listLog.Items.Count == 0)

{

isFinished =true;

}

          else

{

            var joblog = listLog.Items.OfType<SPListItem>().Where(i =>

i[“TypeMessage”].ToString() == TypeMessageLogJobs.End.ToString() &&

((DateTime)i[“Timestamp”]).CompareTo(listLog.Items.OfType<SPListItem>().Max(ii => (DateTime)ii[“Timestamp”])) == 0 ).First();

isFinished =true;

}

}

catch

{

isFinished =false;

}

}

}

});

   return isFinished;

}

Anuncis

Starting custom Sharepoint timer programatically

remote

When you need to start a timer job in SharePoint you can do it from Central Administration with a cool web interface.

There, you can see all timers Jobs in your farm and control their status and logs. But, sometimes we need to start a timer job from a Sharepoint front-end interface. I mean, a simple user wants to start a process that runs in background.

Yes, we have a timer job as a class, you can instantiate and call its RunNow method for starting the process. But, we need to do something else before that.

For security reasons, users can’t start timer jobs in front-end interface. In fact, you must write this Power Shell sentence in the application server or write in your feature activation method in feature receiver class.

PowerShell script

$snap = Get-PSSnapin | Where-Object { $_.Name -eq “Microsoft.SharePoint.Powershell” }
if ($snap -eq $null)
{
Add-PSSnapin “Microsoft.SharePoint.Powershell”
}
# get content web service
$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
# turn off remote administration security
$contentService.RemoteAdministratorAccessDenied = $false
# update the web service
$contentService.Update()

C# code

// SET THE REMOTE ADMINISTATOR ACCESS DENIED FALSE
SPWebService.ContentService.RemoteAdministratorAccessDenied = false;
SPWebService.ContentService.Update();

Remeber that any timer job in Sharepoint is started by SP Timer and you need to restart that service in all farm servers when any change in your custom job are made.

Without modifing RemoteAdministrationAccessDenied to false when you try to start a job programatically a Access denied exception is thrown.

More information:

Custom SPJobDefinition and “Access denied” Error

Custom job and System.Security.SecurityException: Access Denied

Obtenir la definició d’una llista de Sharepoint

Rating_1
La definició de les llistes de Sharepoint, aquell Schema.xml, és la cosa més impracticable que es podien haver inventat.
Obviament estic parlant de quant volem crear llistes utilitzan el Visual Studio 2010. No entenc perquè no existeix cap eina tipus Wizard que ens ajudi a generar una definició de llista en el Visual Studio sabent que són tant complicades d’entendre i més encara de escriure a mà.

Per sort, sempre hi ha solucions. El mateix Sharepoint té un servei anomenat owssvr.dll que ens retorna la definició d’una llista que existeix en un site de Sharepoint.

Per tant els passos son:
1er) Crea la llista utilitzant la interface Sharepoint
2on) Visita la següent página i descarrega el .XML que conté la definició de la llista.
http://YOUR_SERVER_URL/PATH_TO_SITE_CONTAINING_LIST/_vti_bin/owssvr.dll?Cmd=ExportList&List={YOUR_LIST_GUID}

Funciona tant per Sharepoint 2007 com 2010

Easy 😉

Coneixes alguna altre manera?

Ver los detalles de errores en Sharepoint 2010

image_8

A diferencia de Sharepoint 2007 dónde nos era suficiente cambiar en el web.config del directorio virtual inetpub\wss\<puerto de la aplicación web> para poder ver el detalle de los errores en Sharepoint. En la versión 2010 tenemos algo más que cambiar:

CallStack de False a True y CustomErrors de On a Off también debemos cambiarlo en la carpeta de las páginas de aplicación que se encuentra en C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\web.config

En el caso de que fuera la página de administración central entonces lo mismo pero en la carpeta C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\ADMIN\web.config

 

Llegir els logs d’us del Site a Sharepoint 2007

En el meu post anterior parlo dels logs d’us del site, concretament de com activar els logs d’ús del site.

Per poder-los llegir pots fer-ho des de “configuración dels sitio” i llavors seleccionar “informes de uso de sitio”. Una pàgina et detalla molt bé totes les coses que han anat passant en el teu site.

El problema és quan vols crear alguna aplicació o algun element web que vulguis mostrar informació del log. Tal i com comento al post anterior el format del log està definit a Usage Event Logging in Windows SharePoint Services 3.0 però no tenim cap eina senzilla que ens permeti poder llegir el log i obtenir-ne la informació sense tenir que passar per la interpretació del fitxer de logs.

Per internet existeixen solucions que ens poden ajudar a realitzar aquesta tasca:

Load SharePoint 2007 Usage Log Data Using SSIS

SharePoint Log Reader

SharePoint log viewer

SharePoint ULS Log Parser

WSS / MOSS Log File Reader

SharePoint ULS Log Viewer

SharePoint LogViewer – View ULS logs the easy and efficient way

 

 

Activar logs de uso del sitio en Sharepoint 2007

En una instalación de Sharepoint 2007 puedes no tener activado los logs de uso del sitio. Estos logs te informan de las páginas visitadas y los usuarios conectados. Activarlos puede ser util para poder tener una idea del uso que se hace de nuestro sitio.

En esta página se indican los pasos que debes seguir para activarlo:

Activar Informes de uso en Sharepoint 2007

Básicamente desde administración central del Sharepoint debes activarlo en el apartado de Proceso de analisi de uso y despues lo mismo a nivel de SSP.

Estos logs se guardan en la carpeta de instalación del sharepoint. Su estructura es tal y como se indica en el link de Microsoft Usage Event Logging in Windows SharePoint Services 3.0.

 

Windows Server 2008 i Obrir documents de Sharepoint amb Office

Avui toca una curiositat ben curiosa. Resulta que per poder obrir els documents que tenim al Sharepoint 2007 o 2010 amb l’aplicació client d’Office des d’un Windows Server 2008 està per defecte deshabilitada aquesta opció.

Windows Server 2008 developing SharePoint – Can’t connect from Office clients és un post que ens explica molt bé quins passos hem de fer per habilitar-ho.

Simplement heu d’instal·lar una característica que es diu Experiència d’escriptori i ja està.