Category Archives: 12327

Sharepoint 2010 – Consideraciones para la configuración del servicio de búsqueda

El proceso de configuración del servicio de búsqueda en Sharepoint involucra los siguientes pasos generales:

– Crear una cuenta de usuario, dominio o local, que tenga privilegios de acceso sobre todo el contenido de Sharepoint que se va a incluir en el proceso de indexación y búsqueda.

– Con la cuenta de usuario creada, registrarla como cuenta administrada de Sharepoint.

– Crear una aplicación de servicio de búsqueda, Search Service Application, en donde se crean las bases de datos respectivas y adicionalmente se registra la cuenta de servicio respectiva que debe ser la misma de los puntos anteriores.

– Configurar las fuentes de contenido, content sources, de acuerdo a la configuración de los sitios de Sharepoint.

– Ejecutar una tarea de “full crawling” sobre el contenido y verificar que la base de datos se ha alimentado con los registros encontrados.

Ahora bien, cuando el sitio web es configurado con soporte para autenticación Windows (NTLM) y FBA, y adicional a esto fue configurado con un nombre diferente al configurado por defecto, por ejemplo intranet.midominio.com, el proceso varía. Me encontré con las siguientes novedades:

– Por defecto cuando se configura la aplicación del servicio de búsqueda se agrega como fuente de contenido al URL que se encuenta configurada en la zona AAM como por defecto, en nuestro caso sería intranet.midominio.com.

– Al intentar ejecutar la tarea de “full crawling” sobre esta configuración se puede presentar el siguiente error:

The SharePoint server was moved to a different location. ( Error from SharePoint site: HttpStatusCode Found The request failed with the error message: <html><head><title>Object moved</title></head><body> <h2>Object moved to <a href=“%2f_LAYOUTS%2fSharePoint.POC%2fLogin.aspx%3fReturnUrl%3d%252f_vti_bin%252fsitedata.asmx”>here</a>.</h2> </body></html> –. )

De acuerdo a algunos blogs revisados, para solucionar este problema se debería crear una regla de “crawl” que especifique la página personalizada de inicio de sesión (FBA) y adicionalmente las credenciales de acceso. En mi caso este proceso no funcionó.

– Como alternativa adicional, en otros sitios, proponía extender el sitio con autenticación FBA + NTLM a un sitio que solo soporte NTLM, en mi caso por ejemplo intranet.midominio.com:555 sería el sitio extendido con soporte únicamente para autenticación -NTLM.

– En la configuración de fuentes de contenido especificar este nuevo sitio, intranet.midominio.com:555.

Al configurar estas opciones en efecto la tarea de “crawling” finalizó exitosamente y se indexaron todos los items del sitio, sin embargo, al probar el cuadro de búsqueda que se encuentra en la barra de navegación (superior derecha) y colocar una palabra para buscarla, la página de resultados no mostró resultado alguno.

Para identificar el error procedí a habilitar los logs del servicio de búsqueda en nivel “verbose” y adicionalmente descargar la herramienta ULS Viewer (http://archive.msdn.microsoft.com/ULSViewer).

Al revisar los archivos de log, posterior a hacer algunas pruebas de búsqueda para identificar el error, encontré el siguiente mensaje:

Esto implica que aparentemente no existen “Query Processors” habilitados en la granja de Sharepoint para atender las búsquedas enviadas. En específico un Query Processor dentro de la granja de Sharepoint se habilita iniciando el servicio de “Search Query and Site Settings Service” en la sección “Services on Server”.

Adicionalmente se debe habiliar la característica de colección de sitios “Elementos web de Search Server” en: Acciones del Sitio > Configuración del sitio > Administración de la colección de sitios > Características de la colección de sitios.

Posterior a configurar estas opciones no hubo cambios, el cuadro de búsqueda no presentaba ningún resultado.

Finalmente, en la página de administración de la aplicación del servicio de búsqueda, en la barra lateral izquierda, se encuentra la opción “Server name mappings” (http://altfo.wordpress.com/2010/07/08/this-site-this-list-sharepoint-search-not-working-or-returns-nothing/). En esta opción agregué un item con las siguientes opciones:

– Address for indexing: http://intranet.midominio.com:555

– Address for display in search results: http://intranet.midominio.com

Ejecuté una nueva tarea de “full crwaling” y finalmente funcionó el cuadro de búsqueda y resultados.

 

Otras referencias útiles:

http://blogs.msdn.com/b/russmax/archive/2010/04/23/search-2010-architecture-and-scale-part-2-query.aspx

http://blogs.msdn.com/b/russmax/archive/2012/02/15/guide-to-walking-a-sharepoint-2010-search-query-behind-the-scenes.aspx

Sharepoint 2010 – Search Server – Removing the Search Service from the server must be done within the context of a Search Service Application …

En resumen, al tratar de configurar el servicio de búsqueda en una granja de 3 servidores Sharepoint (DB, App, Web FE) el proceso no concluyó exitosamente y se crearon registros huérfanos del proceso. Al tratar de detener el servicio “SharePoint Server Search” se presentó el mensaje de advertencia:

Para lograr detener completamente el servicio:

– Obtener el ID de la aplicación de búsqueda: get-spserviceapplication

– Eliminar la aplicación de Search con el comando: Stsadm -o deleteconfigurationobject -id “id del anterior paso”

– Ingresar al sitio desde la Consola de Administración Central: http://server_sps:puerto/_admin/databasestatus.aspx, revisar si existen base de datos de la aplicación de Search que no fueron configuradas adecuadamente.

– Eliminar los registros desde el command shell: $orphanedDB = Get-SPDatabase | where{$_.Name -eq “MySearchDatabase”} $orphanedDB.Delete()

– Eliminar las bases de datos desde el SQL Server Management Studio.

– Finalmente ejecutar el comando: stsadm -o osearch -action stop

 

 ——– ACTUALIZACIÓN ———– 28/10/2013

Pude percatarme que podría darse el caso de que se mantengan aplicaciones en el sitio SharePoint Web Services relacionados con el servicio SearchService.svc. Para dejar complemetamente limpio el ambiente eliminar aquellos directorios virtuales que contengan el archivo SearchService.svc.

Ejecución de un flujo de trabajo en múltiples items de una lista de Sharepoint

En mi caso particular, tuve la necesidad de ejecutar un flujo de trabajo, construido con SPD, en cerca de 2500 items de una lista de Sharepoint. Luego de navegar por varios minutos encontré el script “Start-OSCSPWorkflow” basado en powershell el mismo que permite ejecutar un workflow sobre una cantidad de items determinada. De acuerdo a las recomendaciones del sitio es importante considerar la capacidad de procesamiento del servidor de Sharepoint para ejecutar cierta cantidad de flujos de trabajo. Para mi escenario, los 2500 items consumió un total de 1.5 GB de Memoria, mientras que el procesador casi no fue impactado de forma constante.

Luego de hacer una importación del script es importante definir como se ejecutará el mismo, por ejemplo, con el parámetro -ItemID se puede colocar una lista de IDs de los items de la lista de Sharepoint que se van a ejecutar separados por comas (,).

Start-OSCSPWorkFlow -SiteURL “Dirección_Sitio” -ListName “Nombre_Lista” -WorkflowName “Nombre_Workflow_SPD” -ItemID 12, 33, 45 -verbose

El script por defecto acepta un máximo de 10 IDs de items de la lista. Esto lo controla con el parámetro -MaxConcurrentWorkflowNumber. Si se va a ejecutar más de 10 elementos deben colocar ejecutar el script con el parámetro -MaxConcurrentWorkflowNumber y un valor superior al de los IDs enviados.

Existe otra forma de ejecución del script y es por medio de una consulta CAML. Si el objetivo es ejecutar un workflow sobre todos los items de una lista:

Start-OSCSPWorkFlow -SiteURL “Dirección_Sitio” -ListName “Nombre_Lista” -WorkflowName “Nombre_Workflow_SPD” -Query ‘<FieldRef Name=”ID” />’ -verbose -MaxConcurrentWorkflowNumber 100

He colocado el valor de 100 al parámetro -MaxConcurrentWorkflowNumber, por ejemplo, si la consulta CAML retorna menos de 100 elementos, caso contrario deben colocar un valor mayor.

El URL de donde pueden descargarse el script es http://gallery.technet.microsoft.com/office/Start-a-Workflow-on-120bffe5, espero sea de su utilidad.

 

Menú de Sharepoint 2010 con imágenes/animaciones flash

Me encontré con un nuevo problema al publicar una animación flash en un sitio de Sharepoint. Resulta que el menú de Sharepoint se presenta detrás de la animación de flash, similar a la imagen presentada.

Para publicar la animación flash utilicé un archivo HTML que hace el llamado a la animación flash y un webpart visor de páginas web para llamar a la página HTML. El truco está en cambiar la etiqueta HTML al siguiente valor:

<param name=”wmode” value=”transparent”>

Espero sea de su utilidad.

Sharepoint 2010 Administration – Error al iniciar el servicio ID 7000 y 7009

Al tratar de reiniciar el servicio “Sharepoint 2010 Administration” se presentó el mensaje de error:

“The service did not respond to the start or control request in a timely fashion.”

Luego de revisar algunos posts ejecuté el siguiente procedimiento:

– ejecuté el comando stsadm -o localupgradestatus, para determinar si era necesaria la actualización de alguna base de Sharepoint. En efecto se presentó un mensaje indicando que la base de configuración requería ser actualizada.

– Traté de ejecutar el comando “psconfig –cmd upgrade –inplace b2b –wait –force” sin tener suerte.

– Traté también de ejecutar el comando “stsadm -o upgrade -forceupgrade”, igualmente sin tener suerte.

– Ejecuté manualmente el asistente de configuración de productos de sharepoint y el mismo culminó sin éxito.

– Se creó la clave de registro “ServicesPipeTimeout” de tipo DWORD en la sección “HKLM\SYSTEM\CurrentControlSet\Control”, con el valor decimal de 60000.

– Actualicé la clave de registro “WaitToKillServiceTimeout” en la sección “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control” con el valor decimal de 120000.

– Reinicié el servidor y ejecuté nuevamente el asistente de configuración de productos de Sharepoint, igualmente sin suerte.

– Finalmente ejecuté el comando “psconfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures” y el procedimiento culminó sin problemas e inició el servicio igualmente.

Espero sea de su utilidad.

Sharepoint 2010: Como ampliar el tamaño de un campo de tipo "Búsqueda" (Lookup) en una lista personalizada

En una lista de Sharepoint, un campo de tipo Lookup se utiliza para hacer referencia a una lista que contiene las opciones o infomación que requerimos. Por ejemplo, en una lista personalizada de Sharepoint puedo mantener el registro de varios documentos de la organización y en otra lista tengo otro campo en el cual deseo seleccionar varios documentos relacionados. Resulta que cuando el nombre del campo que se relaciona es demasiado extenso y además se van a seleccionar varios documentos, la vista del campo relacionado es similar a la siguiente figura:

 

El campo “Documentos Relacioados” se encuentra configurado de la siguiente forma:

 Para ampliar el tamaño de la columna “Documentos Relacionados” se considera la cadena de caracteres de mayor longitud. Es necesario editar la página en donde se encuentre el campo de tipo “Lookup” e insertar un webpart de tipo WCE (Web Content Editor), editar el código HTML e ingresar el siguiente código:

<script src=”/ScriptsDocumentos/jquery-1.7.2.min.js” type=”text/javascript”></script><script src=”/ScriptsDocumentos/jquery.SPServices-0.7.1a.min.js” type=”text/javascript”></script><script type=”text/javascript”>

$(document).ready(function() {

$().SPServices.SPSetMultiSelectSizes({

multiSelectColumn: “Documentos Relacionados”

});

}); </script>

El efecto posterior al ingreso del script es el siguiete:

Los archivos: jquery-1.7.2.min.js y jquery.SPServices-0.7.1a.min.js, pueden descargarlo de este enlace:  http://msmvps.comhttp://blogs.msmvps.com/tech-steps/files/2014/08/2337.JScripts.zip, recuerden incluirlos en una biblioteca de Sharepoint y hacer la referencia correcta al momento de escribir el código en el WCE.

Sharepoint 2010 + Infopath 2010: Como asegurarnos de que una carpeta existe antes de exportar a PDF una vista actual.

En esta serie de posts en relación a InfoPath 2010, tuve que incluir una porción de código para asegurarme de que la carpeta en la cual se van a almacenar los documentos PDF exportados exista. Es necesario agregar una referencia using System.IO; y luego incluir el siguiente código.

 if(!Directory.Exists(@”c:\temp”))
{
Directory.CreateDirectory(@”C:\temp”);
}

Sharepoint 2010 + Infopath 2010: Limitante al exportar vista en PDF y agregarlo como adjunto en un correo

En mi post anterior Sharepoint 2010 – Aprobación de workflows para dispositivos móviles – Parte 3: Código para envío de correo electrónico de notificación, había publicado la siguiente porción de código:

/*Crea un document PDF con la vista actual*/
this.CurrentView.Export(@”c:\temp\” + OrdenCompra + “_MemoMetalicos.pdf”, ExportFormat
.Pdf); /*Importante detener al menos por 10 segundos mientras se crea el documento caso contrario genera un error*/
Thread
.Sleep(10000);

 

El problema resulta que el document PDF que se crea con la function CurrentView no aparace en el directorio destino hasta que toda la función o hilo de ejecución finaliza, por tal motive es que cuando al tartar de agregarlo como adjunto de un correo en el mismo paso (hilo de ejecución) se presenta un mensaje de error en relación a que el documento no existe. Al parecer el método Sleep detiene por complete todo el hilo de ejecución por lo que no da paso a que el documento aparezca en el path de destino.

He invertido ya un gran tiempo en internet buscando información al respecto pero solo encontré un enlace indicando el mismo problema pero sin una solución específica.

SOLUCIÓN: tomando en cuenta la limitante antes expuesta tuve que dividir en dos botones tanto la generación del documento como el envío del correo con el adjunto.

Actualización: este es el único URL que encontré donde se menciona el mismo problema: http://www.infopathdev.com/forums/t/22835.aspx

Sharepoint 2010 – Aprobación de workflows para dispositivos móviles – Parte 4: Código Javascript en la página de webparts de Sharepoint

Para completar el ciclo, es necesario crear la página de webparts, agregar un CEW y colocar ahí el código JavaScript necesario para hacer el llamado al servicio web de actualización de items de la biblioteca de documentos.

En específico el CEW debe contener el siguiente código:

<script src=”/Scripts/jquery.min.js” type=”text/javascript”></script>
<script type=”text/javascript”>

function gup( name )
{
  name = name.replace(/[\[]/,”]”);
  var regexS = “[\\?&]”+name+”=([^&#]*)”;
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return “”;
  else
    return results[1];
}

function ActualizaEmbarque()
{
var IDFormulario=gup(‘IDForm’);
var Estado=gup(‘Estado’);
var Gerente=gup(‘Gerente’);

if (Estado==’1′)
{
   Estado=”APROBADO”;
}
else if (Estado==’2′)
{
   Estado=”NO APROBADO”;
}

if (Gerente==’1′)
{
   Gerente=”AprobacionGerente1″;
}
else if (Gerente==’2′)
{
   Gerente=”AprobacionGerente2″;
}

var soapEnv = “<?xml version=\’1.0\’ encoding=\’utf-8\’?> \
<soap:Envelope xmlns:xsi=\’http://www.w3.org/2001/XMLSchema-instance\’ \
xmlns:xsd=\’http://www.w3.org/2001/XMLSchema\’ \
xmlns:soap=’http://schemas.xmlsoap.org/soap/envelope/\’> \
<soap:Body> \
<UpdateListItems xmlns=’http://schemas.microsoft.com/sharepoint/soap/’> \
<listName>Control de Embarques de Chatarra</listName> \
<updates> \
<Batch OnError=’Continue’> \
<Method ID=’1′ Cmd=’Update’> \
<Field Name=’ID’>”+IDFormulario+”</Field> \
<Field Name='”+Gerente+”‘>”+Estado+”</Field> \
</Method> \
</Batch> \
</updates> \
</UpdateListItems> \
</soap:Body> \
</soap:Envelope>”;
$.ajax({
url: “/_vti_bin/lists.asmx”,
beforeSend: function(xhr) { xhr.setRequestHeader(“SOAPAction”, “
http://schemas.microsoft.com/sharepoint/soap/UpdateListItems“);
},
type: “POST”,
dataType: “xml”,
data: soapEnv,
complete: UpdateListItems,
contentType: “text/xml; charset=\”utf-8\””
});
}

function UpdateListItems(xData, status)
{
alert(“Aprobación: ” + status );
}

ActualizaEmbarque();
</script>

El archivo jquery.min.js lo pueden obtener de este sitio http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js.

La parte medular de este código es:

<UpdateListItems xmlns=’http://schemas.microsoft.com/sharepoint/soap/’> \
<listName>Control de Embarques de Chatarra</listName> \
<updates> \
<Batch OnError=’Continue’> \
<Method ID=’1′ Cmd=’Update’> \
<Field Name=’ID’>”+IDFormulario+”</Field> \
<Field Name='”+Gerente+”‘>”+Estado+”</Field> \
</Method> \
</Batch> \
</updates> \
</UpdateListItems> \

Este código es el que construye el cuerpo de la actualización del item utilizando el servicio web de SharePoint.

<listName>Control de Embarques de Chatarra</listName>: hace referencia al nombre de la lista en donde se harán las actualizaciones.

<Method ID=’1′ Cmd=’Update’> \: como es posible enviar varias actualizaciones en un mismo paso, aquí indicamos que existe uno solo (ID=’1′) y que sera de una operación de actualizacipón (Cmd=’Update’).

<Field Name=’ID’>”+IDFormulario+”</Field> \: utilizando el parámetro enviado en el URL, indicamos cual es el ID del item que vamos a actualizar.

<Field Name='”+Gerente+”‘>”+Estado+”</Field> \: aquí indicamos el campo del item que vamos a actualizar y el valor respectivo. Es importante mencionar que si el nombre del campo posee espacios en blanco debe ir en el formato: “Nombre_x0020_Campo”, la cadena “_x0020_” representa a un espacio en blanco.

ACTUALIZACIÓN: para visualizar el nombre de campo que se debe colocar en el XML Field Name se recomienda ingresar a la configuración de la lista y hacer clic en el campo, revisar en el URL el parámetro Field. Esto es de utilidad en el caso de que el campo contenga tildes o sea demasiado largo, por ejemplo Field=Aprobaci%5Fx00f3%5Fn%5Fx0020%5FAprobador. es necesario reemplazar %5F por un _, para este caso _x00f3_ representa a una ó.

Si se requiere actualizar más campos simplemente se deben agregar más secciones del tipo <Field Name='”+Gerente+”‘>”+Estado+”</Field> \.

 

Espero que esta serie de posts sean de su utilidad.

Sharepoint 2010 – Aprobación de workflows para dispositivos móviles – Parte 3: Código para envío de correo electrónico de notificación

A pesar de que un correo electrónico puede ser enviado utilizando una acción de SPD, en este caso particupar para la plantilla de formulario de InfoPath 2010 fue necesario incluir código C# dentro de las acciones de un botón para poder enviar el correo de notificación junto con el enlace adjunto de la página con los parámetros necesarios para poder hacer la aprobación de un item desde el correo electrónico.

El código C# ingresado es el siguiente:

 try
{
/*Recupera algunos campos para enviar por correo electrónico desde INFOPATH*/
XPathNavigator CamposFormulario = this.MainDataSource.CreateNavigator().SelectSingleNode(“//my:myFields/my:CAMPOS_APOYO/my:IDForm”, this.NamespaceManager);
String IDFormulario = CamposFormulario.Value;
XPathNavigator NombreF = this.MainDataSource.CreateNavigator().SelectSingleNode(“//my:myFields/my:GENERAL/my:NoOrdenCompra”, this.NamespaceManager);
String OrdenCompra = NombreF.Value;
XPathNavigator CorreoGerenteUno = this.MainDataSource.CreateNavigator().SelectSingleNode(“//my:myFields/my:APROBACION_METALICOS/my:CorreoGerente1”, this.NamespaceManager);
String CorreoGerente1 = CorreoGerenteUno.Value;
XPathNavigator CorreoGerenteDos = this.MainDataSource.CreateNavigator().SelectSingleNode(“//my:myFields/my:APROBACION_METALICOS/my:CorreoGerente2”, this.NamespaceManager);
String CorreoGerente2 = CorreoGerenteDos.Value;

/*Crea un document PDF con la vista actual*/
this.CurrentView.Export(@”c:\temp\” + OrdenCompra + “_MemoMetalicos.pdf”, ExportFormat.Pdf);

 

/*Importante detener al menos por 10 segundos mientras se crea el documento caso contrario genera un error*/
Thread
.Sleep(10000);

 

/*Crea un nuevo objeto del tipo mail*/
MailMessage
mail = new MailMessage();
SmtpClient SMTPServer = new SmtpClient(“<servidor de correo>”);
mail.From =
new MailAddress(“<dirección de correo del remitente>”);
mail.To.Add(CorreoGerente1);
mail.Subject =
“Aprobación de Orden de Compra – ” + OrdenCompra;

 

 

AlternateView av = AlternateView.CreateAlternateViewFromString(“Se ha generado una nueva Orden de Compra que requiere ser aprobada por usted. <br> En el documento adjunto encontrar los detalles de la Orden de Compra. <br><br> Para APROBAR la Orden de Compra hacer clic <a href=’http://<URL del servidor y la biblioteca>/paginaWebService.aspx?ID=” + IDFormulario + “&Gerente=1&Estado=1′>AQUÍ</a> <br><br> Para NO APROBAR la Orden de Compra hacer clic <a href=’http://<URL del servidor y la biblioteca>/paginaWebService.aspx?ID=” + IDFormulario + “&Gerente=1&Estado=2′>AQUÍ</a>”, null, “text/html”); Attachment adjunto;
adjunto =
new Attachment(@”c:\temp\” + OrdenCompra + “_MemoMetalicos.pdf”);
mail.Attachments.Add(adjunto);
SMTPServer.Send(mail);
MessageBox.Show(“Correo enviado exitosamente. El formulario se cerrar automticamente en 5 segundos.”);
}
catch (Exception ex)
{
MessageBox.Show(“Error: ” + ex.Message);
}
finally
{ 
Thread.Sleep(5000);
Application.Quit(
true);
}

mail.AlternateViews.Add(av);

La parte clave de este código es la creación del objeto AlternateView ya que el cuerpo del mensaje debe ser enviado en formato HTML para poder incluir los enlaces de aprobación, en el caso de que se requiera enviar únicamente texto plano se puede utilizar el método “mail.body(“cuerpo del mensaje”);.

El formato de los enlaces de aprobación es: <a href=’http://<URL del servidor y la biblioteca>/paginaWebService.aspx?ID=” + IDFormulario + “&Gerente=1&Estado=1′>AQUÍ</a> , en este enlace se hace referencia a la página de webparts “paginaWebService.aspx” en donde se encuentra incluido un CEW con el código javascript necesario para hacer la actualización del item de la biblioteca de formularios InfoPath.

Adicionalmente se envían los parámetros necesarios para hacer el llamado al servicio web de actualización de items.

 

En la siguiente parte revisaremos el código JavaScript incluido en el CEW que hace el llamado al servicio web para hacer la actualización del item de la biblioteca de documentos.