Archivo

Archive for the ‘Tips’ Category

[How to] Crear un servicio de Windows

junio 22, 2012 Deja un comentario

Buenas,

En una de mis actividades del día tengo que crear un Servicio de Windows que se encargue de depurar algunas tablas en la Base de Datos, y como parte de mi intento por seguir escribiendo en este Blog, aquí les platico como es que hago este servicio.

Lo primero es Crear el Proyecto:

1.- Creamos un proyecto desde Visual Studio, con la plantilla de: “Windows Service”

image

Asignamos el nombre correspondiente. Lo que vemos en el proyecto son dos archivos, uno llamado Service1.cs y el Program.cs.

 

image

Para observar el código de Service1.cs basta con hacer clic derecho en el fondo gris que nos aparece y seleccionar ver código, o bien presionando F7, como se pueden dar cuenta, aquí estás los métodos para iniciar el Servicio y para Detenerlo. Aquí escribiéremos el código que necesitemos para cuando se ejecuten estos eventos.

Bien ahora podemos editar algunas de las propiedades de nuestro servicio como son:

  Nombre Descripción
Propiedad pública AutoLog Indica si los comandos Iniciar, Detener, Pausar y Continuar deben notificarse en el registro de eventos.
Propiedad pública CanHandlePowerEvent Obtiene o establece un valor que indica si el servicio puede controlar notificaciones de los cambios de estado de la alimentación del equipo.
Propiedad pública CanHandleSessionChangeEvent Obtiene o establece un valor que indica si el servicio puede controlar eventos de cambio de sesión recibidos de una sesión de Terminal Server.
Propiedad pública CanPauseAndContinue Obtiene o establece un valor que indica si se puede pausar y reanudar el servicio.
Propiedad protegida CanRaiseEvents Obtiene un valor que indica si el componente puede generar un evento. (Se hereda de Component).
Propiedad pública CanShutdown Obtiene o establece un valor que indica si se debe informar al servicio de que el sistema se está cerrando.
Propiedad pública CanStop Obtiene o establece un valor que indica si puede detenerse el servicio una vez se ha iniciado.
Propiedad pública Container IContainer that contains the Component.’ data-guid="820b3092646429b7ca584d7070fb2741">IContainer that contains the Component.’ data-guid="820b3092646429b7ca584d7070fb2741">Obtiene IContainer que contiene Component. (Se hereda de Component).
Propiedad protegida DesignMode Component is currently in design mode.’ data-guid="92b14b816d9ff2682c4a51ee3ff07f92">Component is currently in design mode.’ data-guid="92b14b816d9ff2682c4a51ee3ff07f92">Obtiene un valor que indica si Component está actualmente en modo de diseño. (Se hereda de Component).
Propiedad pública EventLog Obtiene un registro de eventos que se puede utilizar para escribir la notificación de llamadas de comandos de servicio, como Iniciar y Detener, en el registro de eventos de aplicación.
Propiedad protegida Events Component.’ data-guid="41716543b8cc97b6827325125b214887">Component.’ data-guid="41716543b8cc97b6827325125b214887">Obtiene la lista de controladores de eventos asociados a Component. (Se hereda de Component).
Propiedad pública ExitCode Obtiene o establece el código de salida para el servicio.
Propiedad protegida ServiceHandle Obtiene el identificador del control de servicios para el servicio.
Propiedad pública ServiceName Obtiene o establece el nombre corto utilizado para identificar el servicio en el sistema.
Propiedad pública Site ISite of the Component.’ data-guid="75f8b75e7a6898f869c5d0fb7d4dd047">ISite of the Component.’ data-guid="75f8b75e7a6898f869c5d0fb7d4dd047">Obtiene o establece ISite de Component. (Se hereda de Component).

Por el momento solo editaré el nombre del Servicio, ya que las opciones que trae por defecto sirven para mi propósito.

Para hacer más practico el ejemplo, simularé mi tarea y limpiaré una tabla cada 12 horas, entonces en el método OnStart, coloco el siguiente código:

protected override void OnStart(string[] args)
{
    Timer timer = new Timer { Enabled = true, Interval = 43200000 }; //43200000  son 12 horas
    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    timer.Start();
}

Y en el Handler del timer, colocaré mi código:

 

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    //TODO: Código para limpiar mi tabla
    new ProcesoLimpiar().Ejecutar();
}

Este código se ejecutará en mi caso, cado 12 horas.

2.- Agregar un Instalador.

Ahora para terminar vamos a agregar un instalador a nuestro servicio. Para hacer nos colocamos en modo de diseño de nuestro servicio, clic derecho y Add Installer.

En este punto se  agregará una clase llamada ProjectInstaller.cs, que contiene dos archivos, serviceInstaller1 donde indicaremos el nombre del servicio y el tipo de inicio. Además de el nombre a mostrar y una descripción de lo que hace la aplicación. Estos dos últimos datos serán los que se mostrarán en el listado de servicios de Windows.

Por último, si seleccionamos el otro elemento, serviceProjectInstaller1, podemos seleccionar el tipo de cuenta con la que queremos que se ejecute el servicio.

image

Con esto tenemos listo nuestro servicio de Windows.

3.- Instalación y Desinstalación

Desde la línea de comandos podemos instalar/desinstalar un servicio Windows. El comando InstallUtil.exe se instala automáticamente con Visual Studio y podemos ejecutarlo a través de Visual Studio Command Prompt.

Instalación:

InstallUtil.exe miEjecutable.exe

Desinstalación

InstallUtil.exe /u miEjecutable.exe

 

Listo, esto es todo. Espero que les sea de utilidad.

Technorati Tags: ,,,
Categorías:C#, how to, Tips, Windows

[C#] Access to the path {0} is denied. Solución

Buenas,

De regreso al blog, en esta ocasión es más enserio. Aquí hablando de un error común cuando hablamos de acceder a Carpetas o Archivos desde nuestra aplicación.

Seguramente hay muchas opciones para darle solución a esto, y la más común es simplemente ir dicha carpeta, o archivo hacer clic derecho ir a Propiedades y deshabilitar el checkbox de “Read-only”.

Pero que ocurre cuando es una aplicación de escritorio y no tenemos acceso a dicho archivo, bueno para este escenario aquí propongo una solución:

Imaginen que queremos abrir un archivo de texto, con esta instrucción

FileStream fileStream = new FileStream(rutaArchivo, FileMode.Open);

Si nuestro archivo tiene activa la propiedad de “Read-only”, entonces nos mostrará el siguiente error:

image

Para solucionar esto es necesario desactivar la propiedad de solo lectura, y eso lo hacemos con la siguiente instrucción, antes de intentar abrir el archivo en cuestión:

File.SetAttributes(rutaArchivo, 
    File.GetAttributes(rutaArchivo) & ~FileAttributes.ReadOnly);

Con esto ya podemos leer archivos, imágenes, etc. El detalle aquí que puede ocurrir es si nuestra aplicación no se ejecuta como administrador.

Espero que les sea de utilidad.

Saludos.

Categorías:C#, Errores, Tips Etiquetas: , ,

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_X". The conflict occurred in database "DB", table "TableName", column ‘id’.

septiembre 12, 2011 Deja un comentario

Buenas,

Aquí de regreso con el blog. Les platico rápido resulta ser que hay un cambio en la Base de Datos y tengo que agregar unas cuantas tablas, para colocar unos catálogos. Bien ya que tengo estas tablas tengo que agregar unas cuantas relaciones, pero al querer guardar el diagrama SQL Server Management Studio me escupe este mensaje: “The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_X". The conflict occurred in database "DB", table "TableName", column ‘id’.” Como ya lo saben estos chicos de Microsoft no son muy explícitos con sus mensajes.

Así que revisando la relación que se crea, que se ve más o menos así:

 

image

(Para obtener esta cuadro de dialogo, seleccionamos la tabla de la llave foránea y hacemos clic derecho, y seleccionamos Relationships)

Solo tenemos que cambiar la propiedad de “Comprobar datos existentes al crear o habilitar de nuevo.” a un valor NO y listo. Como es un ambiente de desarrollo, eliminar los datos no será problema. Atención en esto que en producción no creo que sea algo bueno.

Con esto se soluciona el mensaje que pone a prueba nuestra paciencia. Espero les ayude.

Saludos.

Technorati Tags: ,,

[Sharepoint 2010] Custom Actions en Sharepoint 2010 dese Visual Studio

enero 3, 2011 2 comentarios

Buenas,

El escenario es el siguiente, necesito colocar un Grupo de acciones dentro de la página de Configuración del Sitio, para dar mantenimiento a unas listas. (limpiar en mi caso). Esto lo podemos hacer, desde la Interface de usuario, pero aquí el objetivo es hacerlo desde nuestra aplicación de SharePoint para que solo despleguemos y esta haga todo el trabajo, además es practico, entre menos configuremos manualmente nuestra aplicación mejor.

Una vez platicado que quiero hacer, les platico como hacerlo:

1.- Tener un Feature.

  • Cuando creamos un proyecto de SharePoint 2010 desde Visual Studio 2010, por default agrega un Feature con el que podemos trabajar, le podemos agregar nombre, descripción etc. Cómo hacemos esto: Abrir Visual Studio, Crear Nuevo Proyecto-> SharePoint 2010->Empty SharePoint Project.

image

2.- Ahora agregamos un ElementManifest a nuestro feature, en el archivo Feature1.Template.xml

image

El XML queda más o menos así:

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" 
        ActivateOnDefault="FALSE"
        AlwaysForceInstall="FALSE"
        AutoActivateInCentralAdmin="FALSE" Hidden="FALSE" Scope="Web"
        Description="Permite Limpiar las Listas"
        Title="Limpiar Listas 11">
    <ElementManifests>
      <ElementManifest Location="Listassss\Elements.xml" />
    </ElementManifests>
</Feature>

 

La parte de Location se refiere al XML que contiene la definición de nuestro Grupo de Acciones, y como lo agregamos de la siguiente manera, clic derecho en nuestra solución->Add->New Item…, y seleccionamos Empty Element, con el nombre que mejor les guste: mis caso Listassss

image

3.- Aquí viene la definición de nuestro Grupo de Acciones, y las acciones mismas. En mi caso solo un link que apunta a mi blog, pero podemos agregar un query string para poder manipular datos de nuestras listas den el evento Load de alguna ASPX que tengamos. El XML se ve así:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomActionGroup Description="Revisar el Blog del desarrollador" 
                     Id="BlogDelNor" ImageUrl="/_layouts/images/medios/agregar.png"
                      Location="Microsoft.SharePoint.SiteSettings" Sequence="10000" Title="My ContentPipeline">
  </CustomActionGroup>
  <CustomAction GroupId="BlogDelNor" Id="CustomFeatureLink"  Location="Microsoft.SharePoint.SiteSettings"
                Sequence="10001"
                Title="My Content Pipeline">
    <UrlAction Url="https://mspnor.wordpress.com" />
  </CustomAction>
</Elements>

Con esto es más que suficiente para agregar un grupo en nuestras Configuraciones del Sitio, algo curioso aquí es que si se dan cuenta agregueen la propiedad Location el valor de Microsoft.SharePoint.SiteSettings porque ahí es donde quiero que se vea este Grupo de Acciones, pero aquí les dejo la documentación del MSDN sobre los diferentes sitios en donde podemos agregarlos: http://msdn.microsoft.com/en-us/library/bb802730%28office.14%29.aspx

Y bien el resultado que obtenemos al hacer esto es el siguiente:

 

image

Es un post rápido y sencillo, pero seguro saca a alguien de un apuro y sino, mínimo me sirve de referencia, porque luego se me olvida.

Saludos.

Etiquetas de Technorati:

Categorías:Ejemplos, Sharepoint, Tips

[TFS] Deshacer cambios de cierto usuario en un workspace diferente

diciembre 14, 2010 Deja un comentario

Buenas,

Aquí rápido un tip de como liberar archivos que estén bloqueados por un usuario que ya no trabaja en nuestra empresa, que se fue y dejo atrapados proyectos o archivos, o que por alguna extraña tenían en una maquina virtual y por eso de la fiestas  o que se yo se les olvido la contraseña del Windows Server y no la pueden recuperar (no digo que me paso a mi, solo digo que puede suceder). Lo que tenemos que hacer es lo siguiente desde el prompt de Visual Studio.

tf undo $/pathArchivoOSolucion /workspace:nombredeWrokspace; domino\usuario /server:nombreServidor/recursive

Y listo, con esto liberamos los archivos a los que ya no tenemos acceso, espero que les sirva.

Saludos.

Etiquetas de Technorati: ,
Categorías:TFS, Tips

[Sharepoint 2010]Error occurred in deployment step ‘Retract Solution’: Cannot start service SPUserCodeV4 on computer

diciembre 1, 2010 1 comentario

Buenas,

image

Aquí rápido un como solucionar este error si es que les ocurre. Como bien lo dice el mensaje al parecer tenemos un servicio detenido así que solo tenemos que iniciarlo, para ello vamos hacemos lo siguiente:

1.- Central Administration -> System Settings -> Manage services on server

2.- Localizamos el servicio de "Microsoft SharePoint “Microsoft SharePoint Foundation Sandboxed Code Service" y lo iniciamos

Listo!!

espero que les sea de utilidad.

Etiquetas de Technorati: ,,
Categorías:Errores, Sharepoint, Tips

[SharePoint 2010] Poblar datos en la instancia de una lista con datos múltiples (lookupmulti)

agosto 24, 2010 1 comentario

Buenas,

Creo que es el primer post de Sharepoint que escribo :P. Bueno les comento cual es el caso rápido como sabemos nosotros podemos poblar con datos una lista desde la instancia para esto contamos con un tag llamado Data y otro llamado DataSource. Yo ocupo el primero… y la sintaxis es más o menos asi

<?xml version="1.0" encoding="utf-8"?><Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="milista"
                OnQuickLaunch="TRUE"
                TemplateType="000000"
                FeatureId="bd6f49e7-68ac-4988-b6ad-eff181bfdd02"
                Url="listas/milista"
                Description="">    
    <Data>
      <Rows>
        <Row>
          <Field Name="Id">1</Field>
          <Field Name="Nombre">NOMBRE1</Field>
        </Row>
      </Rows>
    </Data>
  </ListInstance>
</Elements>

Hasta aquí todo bien, creo que esto lo encuentran en la documentación del MSDN-

http://msdn.microsoft.com/en-us/library/ms478860.aspx

Pero que pasa si quiero mandar múltiples valores por ejemplo en un campo Lookupmulti, bien aquí la solución lo que tenemos que hacer es lo siguiente:

<Data>
  <Rows>
    <Row>
      <Field Name="Id">1</Field>
      <Field Name="Nombre">1;#nombre1;#2;#nombre2</Field>
    </Row>
  </Rows>
</Data>

Solo tenemos que  separarlos con “;#” pero es importante que coloquemos el ID y el VALOR para que esto funcione, recuerden que solo es para campos que aceptan valores múltiples.

Espero que les sirva y sino lo pongo porque luego sirve de referencia para  mi, porque se me olvida 😛

Etiquetas de Technorati: ,
Categorías:Sharepoint, Tips