miércoles, 21 de septiembre de 2011

Utilizar TFS 2010 desde VB 6

Pequeño apunte para que no se me olvide.

Microsoft publicó hace un tiempo un proveedor / componente para permitir que productos que no soportan de forma nativa la conexión con el control de versiones de TFS puedan soportarlo.

Según la documentación de aquí,​ este proveedor permite conectar a TFS 2010 desde, entre otros, Visual Studio .NET 2003, Visual Visual Basic 6 SP6 y SQL Server Management Studio.

Mi experiencia personal ha sido con VS.NET 2003 y funciona 'de lujo' así que entiendo que con el resto de productos funcionará también perfectamente.

¡Ojo! Requiere .NET 4.0 y Team Explorer 2010 para funcionar. El proveedor está disponible para su descarga en el enlace anterior.

viernes, 9 de septiembre de 2011

Excepción BadImageFormatException en IIS 7.5

Ayer tuvimos algún 'pequeño' problema al generar un entorno de prueba de una aplicación web ASP.NET. La situación más o menos vino a ser la siguiente:

Problema:

Al acceder a la dirección web de la aplicación, se produce una excepción de ASP.NET del tipo BadImageFormat.

Solución (¿solución?):

Fácil (yujuu!) El equipo en el que la aplicación está instalada es un Windows 7 en 64 bits, con lo que si está dando esa excepción, el sospechoso más habitual indica que el proyecto en Visual Studio está compilado en 32 bits, así que para solucionar el problema, basta con acceder a las propiedades del proyecto y especificar que la compilación sea compatible con 'Any CPU', tal y como vemos en la siguiente captura (Como el proyecto es en VB.Net, la captura corresponde a las propiedades de un proyecto en ese lenguaje)





Listo. Cambiamos la opción de compilación, compilamos la solución y la instalamos, y a funcionar… un momento, ¿no funciona?

Problema 2:

Al acceder a la aplicación ya compilada correctamente, aparece una nueva excepción. Esta excepción, de la que no tengo captura, decía que no podía cargarse en memoria uno de los ensamblados referenciados por la aplicación (en concreto se trata de un ensamblado Interop) toca 'bucear' un poco en la excepción y darle un poco al 'coco'… Vale, ya lo tenemos!!!

Solución 2:

La segunda excepción está directamente relacionada con la primera, ya que al compilar la aplicación para 'Any CPU' hemos conseguido que la aplicación arranque correctamente en IIS (64 bits) peeero cuando esa aplicación realiza una instancia del componente Interop (compilado en 32 bits) resulta que no puede crear los objetos porque no son compatibles. Menos mal que IIS 7.5 tiene la opción de permitir aplicaciones en 32 bits… ¿dónde?

Vamos al listado de los Application Pools, y en el Pool asociado a la aplicación vamos a las opciones avanzadas:



Aceptamos el cambio, IISReset por si acaso, y a volar!!!!



Explicaciones:

El primer error como he comentado estaba provocado por el tipo de compilación del proyecto. Al compilarlo en 32 bits, los procesos de IIS que se ejecutan en 64 bits no eran capaces de arrancar la aplicación, con lo que cambiamos el modo de compilación a 'Any CPU' para que el compilado sea capaz de adaptarse tanto a 64 como a 32 bits (opción recomendada)

El segundo error estaba provocado precisamente por el cambio realizado en el primer punto, ya que al iniciar la aplicación en 64 bits, cualquier instancia que se realice de ensamblados o dll's compilados en 32 bits, sencillamente 'casca'

Consideración Especial:

Vistos los dos problemas que nos aparecieron, entiendo que la directa hubiera sido configurar el IIS para que permitiera aplicaciones en 32 bits, pero, ¿dónde está la gracia si lo solucionamos tan rápido y sin tener que pensar?

Nota: El segundo problema (ensamblado Interop) en este caso parecía claro que era por una compilación en 32 bits, eso NO quiere decir que en todos los casos esta solución sea válida al 100%.

martes, 6 de septiembre de 2011

Los Informes de TFS 2010 no funcionan (no funcionaban)

Ayer al instalar las plantillas de Scrum para TFS 2010 de Microsoft (Visual Studio Scrum 1.0) me di cuenta de que los informes de estado de TFS no estaban funcionando. Estos informes son los que se utilizan para revisar el estado de un proyecto en TFS (Tareas finalizadas / pendientes, número de Bugs, etc)
Lo que sucedía es que cada vez que accedía a uno de los informes, el servidor de Reporting devolvía este error:
"Error al procesar el informe. (rsProcessingAborted)
Error de ejecución de consulta para el conjunto de datos 'dsBurndown'. (rsErrorExecutingCommand)
Para obtener más información acerca de este error, vaya al servidor de informes en el equipo del servidor local o habilite los errores remotos
"

Tras mucho mirar por ahí y realizar pruebas, la solución resultó ser 'medianamente' sencilla.
El problema, por lo que pude comprobar estaba en el procesamiento del cubo OLAP explotado por los informes. Por lo visto, la primera vez que se tiene que procesar el cubo no funciona directamente desde la herramienta del SQL Management Studio, sino que hay que hacerlo a mano.
¿Cómo lo hacemos a mano? TFS dispone de una serie de Servicios Web de administración que, entre otras cosas, permite precisamente eso. El servicio web en concreto es el que se llama "WarehouseControlWebService" la url de acceso es: http://servidorTFS:puerto/tfs/TeamFoundation/Administration/v3.0/WarehouseControlService.asmx
Una
vez que accedemos al Servicio, hacemos clic en la operación "ProcessAnalysi​sDatabase", establecemos el valor del parámetro "processingType" a Full (tal cual está escrito, es un parámetro de tipo string) y hacemos clic en "Invoke"
Una vez realizada esta operación, teóricamente deberíamos ser capaces de procesar el cubo de nuevo desde el Management Studio, pero no lo he probado, ya que lo que quería era que los informes funcionasen y... voilá, funcionan!
NOTA: Conviene destacar que no he realizado un estudio en profundidad del problema, por lo que no descarto que vuelva a aparecer; simplemente me ha resultado de utilidad constatar que al regenerar el cubo mediante el servicio web de TFS los informes empiezan a funcionar correctamente. ¡Ya tenemos informes de "Sprint Burndown"!

miércoles, 12 de mayo de 2010

Tipos de contenido multi-idioma en Sharepoint


Objetivo

El objetivo de este documento es explicar el procedimiento a seguir para generar tipos de contenido con soporte para varios idioma.
Al final del documento conseguiremos un Tipo de contenido cuyas columnas se mostrarán en el idioma del sitio en el que estemos.
Captura del resultado en un sitio en inglés:


Captura del resultado en un sitio en español:


Consideraciones previas

Entorno:
Visual Studio 2008
Visual Studio 2008 extensions for Windows SharePoint Services 3.0 (version 1.3) Sharepoint Server 2007
Procedimiento
Creación del proyecto
En Visual Studio 2008, creamos un Nuevo proyecto vacío, de tipo Sharepoint:


Y elegimos el nivel máximo de seguridad (Full Trust)


Creación del tipo de contenido

Hacemos clic con el botón derecho del ratón sobre el nombre del proyecto que hemos creado, y elegimos “Add / New Item…”
Seleccionamos la plantilla de “Content Type” y hacemos clic en “Add”


Seleccionamos el tipo de contenido ‘Base’ del que deseamos partir y hacemos clic en “OK”.


En este documento trabajaremos
con un tipo de contenido básico al que no se le añadirá ningún manejador de
eventos, ya que el procedimiento elegido funcionará de la misma manera si
añadimos los manejadores de eventos. Se ha querido mantener el documento lo más
liviano posible.

Como observamos en la siguiente captura, en la ventana del visor de WSP (WSP View) ha aparecido la entrada correspondiente a la característica que acabamos de añadir:


Haciendo doble clic en el archivo “feature.xml” accedemos a la definición de la característica, que indica cómo se muestra la misma en la pantalla “Características de la colección de sitios”. En este archivo realizaremos los primeros cambios para disponer de nuestro tipo de contenido
multi-idioma.
Definición de la característica por defecto:


Definición de la característica modificada:


Como podemos observar en el código definitivo, hemos modificado la siguiente información:
* Title à Utilizamos el ‘token’ $Resources: para indicar que el valor lo obtendremos de un archivo de recursos.
* Description à Idéntico al anterior.
* DefaultResourceFile à Sustituimos el valor original “core” por el personalizado “_Res”. Al establecer este valor, el sistema buscará los recursos necesarios en una carpeta dentro de
la estructura física de carpetas en la que se instala la característica.

Creación de las columnas del tipo de contenido

En la ventana de “WSP View” hacemos doble clic sobre el archivo “Multi1.xml” para acceder a la definición del tipo de contenido.
Definición del tipo de contenido por defecto:


Definición del tipo de contenido modificada:


Las modificaciones realizadas son:
* ContentType.Name à añadimos el ‘token’ para el archivo de recursos.
* ContentType.Description à añadimos el ‘token’
* Field.DisplayName à añadimos el ‘token’
* Field.DisplaceOnUpgrade à añadiendo este atributo indicamos al sistema que si ya existe una definición para el campo, fuerce actualizaciones de propiedades del campo con los valores que se especifican en esta definición de campos. Con este atributo conseguimos que el tipo de contenido ‘raíz’ que estamos creando pueda actualizar los valores de sus columnas en posteriores instalaciones.
Esta actualización ‘forzada’ sólo se realiza en el tipo de contenido ‘raíz’, todos los tipos de contenido que hereden del raíz (al haberse incluido en una biblioteca, por ejemplo) NO se actualizan.

Añadir un archivo de recursos

Hasta el momento hemos utilizado el ‘token’ “$Resources:” para indicar al sistema que el valor del atributo reside en un archivo de recursos; pero, ¿cómo incluimos estos archivos al sistema?
El objetivo de esta parte del documento es conseguir la siguiente estructura en la carpeta de instalación de la característica:


Cada vez que el sistema encuentre el ‘token’ “$Resources:” en los archivos de definición de la característica y/o del tipo de contenido, irá a buscar los recursos a la carpeta “Resources” que aparece en la captura anterior.
Accedemos en Visual Studio al explorador de soluciones, y generamos la siguiente estructura de carpetas en el proyecto:


Como vemos en la captura anterior, tenemos que ‘recrear’ la estructura física que tendrá la característica una vez instalada en el servidor Sharepoint.
En la carpeta “Resources” hacemos clic con el botón derecho del ratón y elegimos Add, New Item… y elegimos la plantilla de archivo de recursos:


Haciendo doble clic en el archivo “Resources.resx” accedemos al archivo de recursos y generamos tantas entradas como ‘tokens’ hayamos utilizado:


Este primer archivo de recursos será el utilizado cuando el idioma del sitio no tenga ningún archivo de recursos asociado. Dicho de otra forma, determina los literales por defecto del tipo de contenido y su característica asociada.

Generar el paquete de la solución

En el explorador de soluciones, hacemos clic con el botón derecho del ratón sobre el proyecto y elegimos ‘Package’
Esta operación nos genera el archivo WSP que instalaremos en el servidor Sharepoint.
La instalación o despliegue de soluciones WSP se escapa al alcance de este documento, por lo que se asume que el procedimiento de instalación es conocido por todos.

Resultado

Una vez instalada la característica y desplegada en los portales necesarios, aparecerá en la página de “Características de la colección de sitios”


Antes de activar la característica, vamos a fijarnos en los literales que aparecen en la captura… son los literales definidos en el archivo de recursos, sí; pero, un momento, ¡según el botón “Activar”, el sitio de Sharepoint está en castellano! ¿Qué ha pasado aquí?
Como hemos comentado antes, el sistema intenta localizar un archivo de recursos que se ajuste al idioma del sitio en el que estamos. Si no lo encuentra utiliza el archivo por defecto (en este caso el único que hemos añadido)

Añadiendo más archivos de recursos

Para añadir más archivos de recursos (teóricamente uno para cada idioma que tengamos disponible) vamos en el proyecto a la carpeta Resources y añadimos un nuevo archivo de recursos, que se llamará exactamente igual que el primero que hemos añadido, pero con el sufijo id-ID que indicará el idioma y la localización de los recursos. La estructura de esta carpeta Resources quedará:


El contenido del archivo tiene que ser exactamente igual que el archivo de recursos por defecto, obviamente traducido al idioma del archivo (en este caso es-ES, español de España)


Volvemos a generar el paquete WSP, lo reinstalamos en el servidor Sharepoint, y observamos el resultado:


¡¡¡Ya tenemos la característica traducida!!!
Ahora sólo hace falta activar la característica y ya tenemos el tipo de contenido generado tal y como se veía al principio, con distintos literales para cada idioma.
Detalle del tipo de contenido:


Añadir este tipo de soporte multi-idioma es relativamente sencillo, pero hay que tener en cuenta las limitaciones especificadas anteriormente. Una vez que un tipo de contenido se utiliza en una lista de Sharepoint, las modificaciones realizadas al tipo de contenido raíz mediante este procedimiento NO se trasladan a dichos tipos de contenido ‘hijos’.

martes, 24 de junio de 2008

Utilizar formularios abstractos desde Visual Studio 2008

El IDE de desarrollo de Visual Studio tiene ciertas limitaciones para diseñar formularios de Windows Forms que heredan de una clase abstracta; en este artículo se propone un patrón de diseño que rodea dichas limitaciones.






Implementación de Formularios Base
Una de las características más eficaces de la herencia es la posibilidad de realizar cambios en una clase base que se propagan a las clases derivadas. Cuando hablamos de aplicaciones de tipo Windows Forms, lo anterior implica que podemos tener un formulario base del que hereden el resto de formularios de la aplicación, facilitando que la aplicación sea homogénea, así como la reutilización de código.
En el presente artículo se va a tratar una problemática muy común con el uso de clases bases y heredadas en formularios y se van a ofrecer alternativas para facilitar estas operaciones.

Problema:
Cuando trabajamos con formularios heredados lo hacemos con el objeto de tener una serie de clases (formularios) base de los cuales hereden todos los formularios de nuestra aplicación, creando así pantallas homogéneas tanto en diseño como en el código asociado. Sin embargo, con esta arquitectura aparece un problema en tiempo de diseño cuando la clase base de la que heredamos es una clase abstracta. En la siguiente captura vemos el error que aparece al abrir en el diseñador de Visual Studio la clase ‘heredada’:




Como podemos observar en la captura, El diseñador de Visual Studio nos indica que no puede crear una instancia de la clase ‘base’ porque está declarada como una clase abstracta.


Detalle de la clase Base:
Public MustInherit Class Base
Inherits Form

Detalle de la clase heredada:
Public Class Inherited
Inherits Base

En este punto más de uno estará pensando ‘¿Por qué está intentando crear una instancia de la clase base, si yo estoy abriendo la clase heredada?’ En el blog de Brian Pepin tenemos las razones de este comportamiento, aunque más adelante en este documento se darán más detalles.
Una vez revisado el artículo de
Brian Pepin, alguien estará pensando ‘vale, pues no utilizaré formularios abstractos’ aquí no voy a intentar convencer a nadie de que la utilización de este tipo de clases es imprescindible, pero me vais a permitir que ponga un ejemplo:
Ejemplo:
Todos los formularios de tipo ‘Mantenimiento’ de la aplicación tienen un botón ‘Grabar’ que se encarga de guardar la información introducida en una Base de Datos. Para solucionar este requerimiento, tomamos la siguiente decisión:



  1. Genero una clase base que, heredando de la clase ‘Form’ incorpore el botón. De esta forma, cada vez que incorporemos un formulario de tipo ‘Mantenimiento’ a la aplicación, en lugar de que herede de ‘Form’, indicamos que hereda de nuestra clase base y ya tenemos el botón automáticamente en el formulario, con el diseño que le hayamos dado en la clase base. Si tenemos que cambiar el diseño de dicho botón, lo haremos en la clase base y el resto de formularios automáticamente aplicarán el nuevo diseño.

  2. Además, yo quiero que este botón en todos los formularios realice la misma operación (SaveData) y que además sólo la realice si se ha validado la posible información existente en la pantalla (ValidateData) para esto vamos a codificar el evento del botón en la clase base, de forma que ese comportamiento se ‘herede’ por todos los formularios derivados de nuestra clase base. En este punto no sabemos qué campos tenemos que validar, ni tampoco que objeto de la Base de Datos vamos a actualizar, con lo que decidimos generar la firma para las dos llamadas en la clase base, obligando mediante ‘MustOverride’ a todas las clases derivadas a que implementen esas funciones, ya que ellas son las que realmente saben con qué datos están trabajando:

    Protected MustOverride Function ValidateData() As Boolean
    Protected MustOverride Function SaveData() As Boolean

  3. En este punto, Visual Studio nos va a obligor a marcar la clase como ‘MustInherit’ ('Base' must be declared 'MustInherit' because it contains methods declared 'MustOverride'.) y esto ¿qué significa? Al marcar la clase base como ‘MustInherit’ la estamos convirtiendo en una clase abstracta y acabamos en la situación del error anterior.

Como veis en el ejemplo no es descabellado llegar a utilizar estas clases abstractas; sin embargo, como explicaba anteriormente no podemos editar en modo ‘Diseño’ los formularios que hereden de una clase abstracta.

Explicación:
(Interpretación libre del artículo de Brian Pepin) Cuando abrimos un formulario en la vista de diseño, el IDE de Visual Studio lo que hace es crear una instancia de la clase base de ese formulario, diseñar los controles existentes en la clase base mediante la rutina ‘InitializeComponents’ y a continuación mediante su propia rutina ‘InitializeComponents’ realizar su propio diseño personalizado.
Al trabajar de esta manera, cuando la clase base es una clase abstracta el diseñor devuelve la excepción anterior ya que las clases abstractas no pueden ser instanciadas directamente.

Solución Propuesta:
En múltiples foros, artículos y demás recursos de la red, se propone utilizar la compilación condicional para solucionar este problema, con estas soluciones, el inicio de la clase base sería:
#If CONFIG = "Release" Then
Public MustInherit Class Base
Inherits Form
Public MustOverride Function ValidateCode() As Boolean
Public MustOverride Function LoadData() As Boolean
#Else
Public Class Base
Inherits Form

Public Overridable Function ValidateCode() As Boolean
Throw New NotImplementedException
End Function
Public Overridable Function LoadData() As Boolean
Throw New NotImplementedException
End Function
#End If

Esta técnica funciona correctamente, pero implica tener siempre el componente donde definamos las clases base siempre en modo ‘Debug’ para poder diseñar los formularios de la aplicación; dificultaría la encapsulación de clases base en dll’s independientes, ya que si esa dll está compilada en modo ‘Release’ las clases son abstractas. Adicionalmente, al no marcar los métodos como ‘MustOverride’, corremos el riesgo de que los formularios heredados no implementen dicho método (en este caso daría una excepción, pero en determinadas circunstancias puede ser complicado detectar esas excepciones.
En el blog de Brian Pepin tenemos otra posible solución, que es la que yo he implementado y que explicaré un poco más adelante. Explicándola en pocas palabras:
El IDE de Visual Studio utiliza ‘Reflexión’ para pintar los formularios; la solución que vamos a utilizar consiste en aplicar un atributo personalizado a la clase base de forma que el IDE al encontrar ese atributo utilice una implementación personalizada de la clase para realizar el ‘pintado’ de los controles en la vista de ‘diseño’.

Descripción de la Solución:
En los fragmentos de código que se verán a continuación he utilizado la raíz ‘Base’



  • Atributo personalizado. Necesitamos un atributo para la clase Base que permitirá indicar qué implementación de la clase se utilizará al acceder en la vista de diseño. Este atributo puede ser único para todas las clases Bases.
    El código del atributo es:
    [AttributeUsage(AttributeTargets.Class)]_
    Friend Class BaseFormAttribute
    Inherits Attribute
    Private _designType As Type
    Public ReadOnly Property DesignType() As Type
    Get
    Return _designType
    End Get
    End Property
    Public Sub New(ByVal design As Type)
    _designType = design
    End Sub
    End Class

    La propiedad ‘DesignType’ especifica que clase (tipo) se utilizará para mostrar el formulario en la vista de diseño. El constructor se ejecutará cuando apliquemos el atributo a la clase base; adicionalmente hemos marcado esta clase con el atributo ‘AttributeUsage’ para indicar que este objeto sólo se aplicaría a tipos ‘Class’ más información en el sitio del
    MSDN.

  • Proveedor. Necesitamos una clase auxiliar que reemplace la lógica de reflexión utilizada por defecto por el IDE con las rutinas necesarias para aplicar la solución. El proveedor heradará de ‘TypeDescriptionProvider’ y se aplicará a la clase base como atributo. Para que cumpla su comentido tendremos que sobrecargar los métodos ‘GetReflectionType’ y ‘CreateInstance’. Este proveedor puede ser único para todas las clases Bases.
    El código del proveedor (simplificado, el código completo está en el proyecto que acompaña a este documento) es:
    Friend Class BaseFormProvider
    Inherits TypeDescriptionProvider
    Private _abstractType As Type
    Private _designType As Type
    Private Sub EnsureTypes(ByVal objectType As Type)
    .........
    End Sub
    Public Overloads Overrides Function CreateInstance(ByVal provider As IServiceProvider, ByVal objectType As Type, ByVal argTypes As Type(), ByVal args As Object()) As Object
    .........
    End Function
    Public Overloads Overrides Function GetReflectionType(ByVal objectType As Type, ByVal instance As Object) As Type
    .........
    End Function
    End Class

    Donde:

    * _abstractType es el tipo de la clase Base.
    * _designType es el tipo de la clase ‘puente’ para la vista de diseño.
    * EnsureTypes se encarga de establecer la clase Base y la clase para Diseño.
    * CreateInstance y GetReflectionType son las sobrecargas utilizadas para evitar que el diseñador llegue hasta la clase base y realice la reflexión en su lugar con la clase para Diseño.

  • Diseñador. Esta clase es la que se utilizará para ‘pintar’ los controles del formulario heredado en la vista de diseño. De esta clase heredará la clase base y contiene toda la parte de diseño de este formulario. Esta clase sólo se utiliza para diseñar; en él añadimos los controles que queremos en la clase base, su ubicación y estilo en pantalla, pero nada más. NO PONDREMOS NADA DE CÓDIGO EN ESTA CLASE. El nombre para esta clase terminará en ‘Designer’ y es necesario un diseñador para cada clase Base.

  • Clase Base. La clase final de la solución; esta clase hereda del diseñador (BaseFormDesigner) y en ella incluiremos TODO el código el código que necesitemos en la clase Base así como las declaraciones de los métodos ‘MustOverride’ que necesitemos. La clase irá decorada con los atributos que hemos generado anteriormente.
    Un ejemplo de código de la clase Base (simplificado, el código completo está en el proyecto que acompaña a este documento) es:
    [TypeDescriptionProvider(GetType(BaseFormProvider)), _
    BaseForm(GetType(BasicDataFormDesigner))]_
    Public MustInherit Class BasicDataForm
    Inherits BasicDataFormDesigner
    Protected MustOverride Function ValidateData() As Boolean
    Protected MustOverride Function SaveData() As Boolean

    Podéis observer la utilización del proveedor, del diseñador y del atributo personalizados en la decoración de la clase.
    Un ejemplo de código adicional en la clase Base (por ejemplo el del botón Grabar del ejemplo:
    Private Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
    If ValidateData() Then
    SaveData()
    End If
    End Sub

    Como he explicado antes, es en la clase heredada donde tendremos que implementar las dos rutinas, hasta el punto de que si no están implementadas no podremos compilar el proyecto.

Consideraciones:



  • Si no necesitáis formularios base abstractos (o dicho de otra forma, si podéis obviar el uso de métodos ‘MustOverride’) no merece la pena que implementéis esta solución.

  • He detectado un pequeño problema en el IDE de Visual Studio: Si modificas la clase base teniendo abierto un proyecto en el que hay formularios que heredan de esa clase base, al abrir uno de ellos en el modo diseño se produce el mismo error que hemos solucionado en este documento. Ahora ya os he rematado y os preguntáis ¿Entonces qué mejoro? No os preocupéis que he indicado que es un problema ‘pequeño’, ya que basta con cerrar el proyecto y volver a abrirlo para que la nueva versión de la clase base se cargue sin problemas (Salir y volver a entrar, el eterno ‘workaround’ de la informática) obviamente los proyectos que no estén cerrados se actualizarán correctamente (actualizando el componente de clases base). De todas formas, si alguien tiene alguna sugerencia al respecto, estaré encantado de escucharla / discutirla.

  • Los formularios heredados tienen que utilizar el último componente especificado como clase base.
    Código Fuente:
    Todo el código fuente que os he enseñado / explicado en este documento está disponible en CodePlex,
    La Release concreta es
    CTSI.Framework.Winforms 1.0.0.0.

martes, 15 de enero de 2008

Dar permisos totales a una unidad de red para .NET

Bufff, no he sido capaz de mantener el blog actualizado; lo confieso soy un desastre.
Bueno, pequeña 'píldora' para facilitar el desarrollo de aplicaciones con Microsoft. NET.

Cuando intentamos cargar un proyecto de VS.NET project desde una unidad de red (por ejemplo la N:) lo normal es que recibamos el siguiente error:

"The project location is not trused."
"Running the application may result in security exceptions when it attemps to perform actions which require full trust."


Lo que está pasando es que .NET por defecto restringe los permisos a ensamblados en la red.
Para dar permisos totales a estas unidades de red, tenemos que añadir un nuevo "Code Group" especificando en formato URL que queremos otorgarle confianza total. Esto podemos hacerlo mediante la herramienta de configuración de .NET Framework o a través de la línea de comando de la siguiente manera:


c:\>caspol -q -machine -addgroup 1 -url file://n:/* FullTrust -name "Unidad N"

Una vez generado este nuevo grupo, cualquier proceso nuevo .NET que arranquemos dará permisos totales a los ensamblados de la unidad N.

OJO con las posibles implicaciones de seguridad, TODOS los ensamblados de la N cogen permisos totales (confianza)

jueves, 15 de noviembre de 2007

Sobrevivir al .NET

Con este título tan lacónico da inicio este nuevo intento por parte de un servidor de intentar registrar asiduamente mis 'guerras' con el fantástico mundo del desarrollo en entornos Micro$oft.

Sed bienvenidos y disculpad cualquier incongruencia que podáis encontrar en este espacio.

Como comento en la descripción del sitio, espero poder publicar pequeños (o no tan pequeños) trucos o antídotos que en una ocasión u otra me hayan podido 'salvar el cuello' -- Bueno, o que me lo podrían haber salvado en alguna otra ocasión.

Nada más, no soy persona de muchas palabras, espero que os resulte útil todo lo que encontréis aquí.

Besitos para ellas y abrazos para ellos.