Code Segment

SharePoint - Instalando webparts remotamente

Feb 23 2006 by csegura @ 19:32

El otro día chateando con Gustavo sobre su post (Un VisualStudio 2005 señor? No gracias, déme un 2003, por favor) hablamos sobre la instalación de los webparts en las maquinas de pruebas. Yo le comente que lo que hacía era copiar el archivo CAB en la máquina remota y ejecutar el stsadm y el RecycleAppPool usando un enlace de terminal server. (archivo .rdp), esto lo tengo en un batch, y necesito un archivo RDP para cada webpart (ya que el nombre del archivo CAB va dentro del RDP). Luego en el Visual Studio tengo un enlace en las herramientas externas que lanza los comandos.

Desde el día en que estuvimos hablando he mejorado el proceso de instalación, ahora tengo un pequeño archivo batch que se encarga de todo. Como pieza clave utilizo el PsExec de SysInternals que me permite ejecutar comandos remotos.

RemoteInstallWebPart.CMD

@echo off
rem %1 - cab file
rem %2 - server machine | IP
rem %3 - path 

rem ===== Copy the webpart
copy /y %1 \\%2\c$\%3

rem ===== Copy the RecycleApp
copy /y MyRecycleAppPools.vbs \\%2\c$\%3

rem ===== Put your server STSADM path
set r_path=c:\archiv~1\archiv~1\micros~1\webser~1\60\bin

psexec \\%2 %r_path%\stsadm -o addwppack -filename c:\%3\%1 -globalinstall -force 
if errorlevel 0 goto Recycle
goto stsadmError

:Recycle
psexec \\%2 cmd /c c:\%3\MyRecycleAppPools.vbs 
if errorlevel 1 goto recycleError

goto end
:stsadmError
echo Error en STSADM
goto end
:recycleError
echo Error en RecycleAppPool
goto end
:end
set r_path=

MyRecycleAppPools.vbs

Set locator = CreateObject("WbemScripting.SWbemLocator") 
Set Service = locator.connectserver(strServer, "root/MicrosoftIISv2") 
Set APCollection = Service.InstancesOf("IISApplicationPool") 
For Each APInstance In APCollection 
    APInstance.Recycle 
Next

Ahra invocando este archivo de comandos se instalan las webparts en un segundo. El archivo MyRecycleAppPools.vbs es una modificación del original al que le he eliminado el msgbox para que no salte el mensaje final.

Ej: RemoteInstallWebPart.cmd   MiWebPart.cab 192.168.99.200  webparts

Como dice mi buen amigo "Escriba un comentario que me haga reir..."

Comments (0)

Excel - Generando MDX

Feb 20 2006 by csegura @ 19:05
Continuando con el trabajo que estaba realizando para mostrar información del Analisys Services en SharePoint, he realizado un pequeño programa en Excel para exportar las sentencias MDX (Nota: todavía no he visto el editor del SQL2005 y puede que este sea una maravilla, el del SQL2000 sin comentarios), con lo cual puedo usar Excel con una tabla dinámica para diseñar el informe y exportar este para usarlo con el webpart de OLAP que estaba realizando. Usando el contenido del un .dwp podríamos generar un webpart completo para importar en SharePoint.

Este ejemplo generará un archivo XML con la definición del informe con esta sintaxis.

<?xml version="1.0" encoding="utf-8"?>
<informe>
  <nombre>Informe de Prueba</nombre>
  <descripcion>Informe de ventas de la base de datos FoodMart 2000</descripcion>
  <conexion>
   OLEDB;Provider=MSOLAP.2;Persist Security Info=True;Data Source=srvdatos;Initial Catalog=FoodMart 2000;
   Client Cache Size=25;Auto Synch Period=10000
  </conexion>
  <mdx>
    <![CDATA[ 
    SELECT NON EMPTY HIERARCHIZE({DrillDownLevel({[Product].[All Products]})}) 
    DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS , 
              NON EMPTY HIERARCHIZE({DrillDownMember(
              {{DrillDownMember({DrillDownLevel({[Customers].[All Customers]})}, 
              {[Customers].[All Customers].[USA]})}}, {[Customers].[All Customers].[USA].[CA]})}) 
              DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON ROWS  
              FROM [Warehouse and Sales] WHERE ([Measures].[Sales Count])
   ]]>
   </mdx>
</informe>

Pasos para hacer nuestro diseñador de informes.

1.- Abrir excel
2.- Crear un informe de tabla dinámica usando el asistente de excel
3.- Configurar el informe a nuestro gusto
3.- Llamar a la macro de exportar informe (yo le he hecho un bonito formulario ...)

Sub ExportaXML(sNombre As String, sDesc As String)
    Dim xmlDoc As DOMDocument
    Dim xmlNode As IXMLDOMNode
    Dim xmlAttribute As IXMLDOMAttribute
    Dim xmlInforme As IXMLDOMNode
    Dim xmlPi As IXMLDOMProcessingInstruction
    Set xmlDoc = New DOMDocument
    Dim xmlText As IXMLDOMText
    Dim sArchivo
    
    sArchivo = Application.GetSaveAsFilename("", "Archivo MDX,(*.xml)", , "Archivo MDX en XML")
    If sArchivo <> False Then
    
        Set xmlPi = xmlDoc.createProcessingInstruction("xml", "version=""1.0""")
        Set xmlNode = xmlDoc.appendChild(xmlPi)
        
        Set xmlInforme = xmlDoc.createElement("informe")
        
        Set xmlNode = xmlDoc.appendChild(xmlInforme)
    
        Set xmlNode = xmlDoc.createElement("nombre")
        Set xmlText = xmlNode.appendChild(xmlDoc.createTextNode(sNombre))
        Set xmlNode = xmlInforme.appendChild(xmlNode)
        
        Set xmlNode = xmlDoc.createElement("descripcion")
        Set xmlText = xmlNode.appendChild(xmlDoc.createTextNode(sDesc))
        Set xmlNode = xmlInforme.appendChild(xmlNode)
    
        Set xmlNode = xmlDoc.createElement("conexion")
        Set xmlText = xmlNode.appendChild(xmlDoc.createTextNode(ActiveSheet.PivotTables(1).PivotCache.Connection))
        Set xmlNode = xmlInforme.appendChild(xmlNode)
    
        Set xmlNode = xmlDoc.createElement("mdx")
        Set xmlText = xmlNode.appendChild(xmlDoc.createTextNode(ActiveSheet.PivotTables(1).MDX))
        Set xmlNode = xmlInforme.appendChild(xmlNode)
        
        xmlDoc.Save (sArchivo)
    End If
        
End Sub

Comments (0)

SharePoint - Conectando csegRollUp

Feb 18 2006 by csegura @ 12:46
He estado pensando en las nuevas características que tendrá la versión 3.5 del csegRollUp (como siempre, si alguien tiene sugerencias que las diga)  por el momento dejo unas pequeñas pistas aquí. He estado trabajando con unas bibliotecas de documentos que contiene un meta dato llamado estado, la idea era mostrar los últimos archivos modificados por cada usuario dentro de un estado en particular, bien para esto basta con hacer una vista de la biblioteca de documentos y mostrar la vista organizada en categorías (cada estado una categoría). Esto esta muy bien pero en ocasiones el diseño ha de ser más funcional y esto es lo que ha salido usando el csegRollUp.

El primer csegRollUp va a mostrar un menú con los distintos estados, seleccionando uno de los estados se mostrarán en un segundo csegRollUp los documentos que tienen  dicho estado.

Para el primer csegRollUp se puede usar un pequeño truco si lo que queremos es hacer una transformación XSLT, que es poner un guión en el nombre de la lista y otro en el nombre de los campos, después podemos nuestro XSLT, (esto se podría hacer con un webpart de contendo, pero lo interesante aquí es aprovechar el interface cell provider de csegRollUp)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method ="html"/>
  <xsl:template match="/">
    <a href="javascript:__doPostBack('','Estado A')">Ver los del estado A</a>
    <br/>
    <a href="javascript:__doPostBack('','Estado B')">Ver los del estado B</a>
    <br/>
  </xsl:template>
</xsl:stylesheet>

Este xslt pasará el estado a un segundo csegRollUp, donde mostraremos los documentos en función del estado, para ello en el segundo:

Lista: Nustra biblioteca favorita
Campos: FileRef,LinkFilename,EncodedAbsUrl,Modified,DocIcon,Author,Estado

XSLT

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" />
  <xsl:template match="/">
    <table class="ms-summarycustombody">
      <tbody>
        <xsl:for-each select="Rows/Row">
          <xsl:sort select="Modified" order="descending"/>
          <tr>
            <td width="24px">
              <img src="/_layouts/images/ic{DocIcon}.gif" alt="{FileRef}"/>
            </td>
            <td width="100%">
              <xsl:value-of select="LinkFilename" />
              <br/>
              <font color="#999999">
                (<xsl:value-of select="substring-before(Modified,' ')" />)
              </font>
            </td>
            <td width="24px">
              <a href="{substring-before(FileRef,LinkFilename)}">
                <img border="0" src="/_layouts/images/folder.gif" alt="Ir a la carpeta"/>
              </a>
            </td>
          </tr>
        </xsl:for-each>
      </tbody>
    </table>
  </xsl:template>
</xsl:stylesheet>

Y por último lo más importante la CAML query que recogerá el valor pasado.

<Where>
  <And>
    <Eq>
      <FieldRef Name="Author" />
      <Value Type='Text'>[UserName]</Value>
    </Eq>
    <Eq>
      <FieldRef Name="Estado" />
      <Value Type='Text'>[CellProvider]</Value>
    </Eq>
  </And>
</Where>

El resultado tras conectar los dos webparts:

Comments (0)

SharePoint - Visual Studio 2005 - WebPart template project

Feb 13 2006 by csegura @ 19:25

Days ago I wrote about how to use msbee to do webparts with Visual Studio 2005, now the toolkit guys have a beta version, I have spent the weekend doing some tests with this beta release and now I'm doing my webparts using Visual Studio 2005. In the beginning I was using the external tools menu to launch the msbuild process with apropiate targets, and later launching other tool with the sign assembly process, finally I have modified the .csproj file because at the moment for SharePoint 2003 I only need use the Net 1.1 framework. Also I added at the Postbuild event the sign assembly process.

In order to use this template you need install MsBee and the .Net 1.1 Framework.

 SharePoint_2003_VS2005_WebPart_Template.vsi V2 corrected version (537,63 KB)

Notes:

1.- Thanks to Remco Ploeg - by detect the sign problem.
2.- V2 Corrected .dwp generation and manifest.xml


------ Operación Generar iniciada: proyecto: WebPartTemplate2, configuración: Debug Any CPU ------

C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Csc.exe /noconfig /warn:4 /define:TRACE;DEBUG /reference:SharePointLibraries\Microsoft.SharePoint.dll
/reference:C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll
/reference:C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Web.dll
/reference:C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Xml.dll
/debug+ /debug:full /optimize-
/out:obj\FX1_1\Debug\WebPartTemplate2.dll
/target:library Properties\AssemblyInfo.cs WebPart1.cs

WebPartTemplate2 -> C:\DEV\SharePoint2003a\WebPartTemplate\WebPartTemplate2\WebPartTemplate2\bin\FX1_1\Debug\WebPartTemplate2.dll

"C:\Archivos de programa\Microsoft.NET\SDK\v1.1\bin\sn.exe" -R
C:\DEV\SharePoint2003a\WebPartTemplate\WebPartTemplate2\WebPartTemplate2\bin\FX1_1\Debug\WebPartTemplate2.dll C:\DEV\SharePoint2003a\WebPartTemplate\WebPartTemplate2\WebPartTemplate2\Key.snk

Microsoft (R) .NET Framework Strong Name Utility Version 1.1.4322.573

Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Assembly 'C:\DEV\SharePoint2003a\WebPartTemplate\WebPartTemplate2\WebPartTemplate2\bin\FX1_1\Debug\WebPartTemplate2.dll'
successfully re-signed

========== Generar: 1 correctos o actualizados, 0 incorrectos, 0 omitidos ==========

Now I'm removing Visual Studio 2003 from my laptop :-)

Comments (8)

SharePoint - Roles, Plantillas y Soluciones

Feb 11 2006 by csegura @ 19:32

Me basto con dedicarle unas horas para solucionar el problema de los Roles del otro día, ¿como? usando Microsoft Access y los servicios web de SharePoint. Por aquí dejo una pequeña demo del asunto, básicamente consiste en añadir los grupos necesarios en el primer nivel, usando el servicio de usuarios y grupos.

Dim userGroups As clsWssUserGroup
Dim permissions As clsWssPermissions
      
Set userGroups = New clsWssUserGroup
Set permissions = New clsWssPermissions

' Conectamos con el sitio
userGroups.Connect sURL
    
' Añadimos los roles de usuarios dentro del sitio
userGroups.wsm_AddRole "ROL1", "Descripción", MascaraPermisos

....

permissions.Connect sURL
    
' Añadimos/Removemos permisos en las listas 
permissions.wsm_RemovePermission "NombreLista", "List", "ROL1", "role"

Una vez que hemos añadido los roles a un sitio estos aparecerán en todas las listas, ahora después podemos ir recorriendo la estructura de nuestro sitio y eliminando los roles que no deban estar en cada una de las listas. Si quiero que una lista solo la modifiquen aquellos que tienen un rol determinado, elimino el rol de colaborador y de lector.

En el archivo adjunto hay una función llamada TestSPRights, para elaborar las mascaras de permisos, necesarias cuando se crean los roles. También hay un par de ejemplos de como usar los servicios web y las clases para dichos servicios, necesitareis usar dos referencias para que funcione el archivo adjunto: MSXML 4.0 o superior y Microsoft Soap Type Library 3.0.

  SharePointWebServicesDemo.zip (75,76 KB)

Comments (0)