Archivo de la categoría: SomeCode

La madurez de MicroFramework 4.2, Vuelve el Basic!

Si bien es cierto que han pasado 25 años desde los primeros micro controladores “todo en uno” de Intel  MCS51 que incluían un interprete “Basic” como “Firmware” y hacían nuestras delicias permitiéndonos encender y apagar “lucecitas” con instrucciones muy simples y sin tener que ahondar en profundos conocimientos… nadie discute que paulativamente aquella tecnología dejo de apasionarnos al ritmo que aparecieron nuevos procesadores y electronicas con mucho mas atractivo; de hecho incluso nos avergonzaba tener que numerar las líneas, pero también es cierto que después de aquellos primeros pinitos quedamos fuera de juego inmersos en complejos y potentes sistemas de 16/32b que embebían todo el chip set en un solo encapsulado… ya sabéis el resto de 32 a 64 y la necesidad de acumular un montón de conocimiento previo sobre el medio para poder terminar encendiendo y apagando nuestra querida “lucecita” 🙂 con la diferencia de haber tenido que escribir un monton de codigo mas … complejidad obliga!

Quizás buscando la moraleja se resumiría desde hace algunos años en la nostalgia de NO tener a mano aquellos viejos cacharros que nos permitían activar una salida de pulso con modulación simplemente con : 10 PWM 100,100,1000 , no quiero aburriros explicando como las nuevas plataformas y procesadores se alejaron cada vez mas del “Basic listo para funcionar” y se aproximaron al preámbulo técnico entre compiladores librerías, inicializaciones y descarga de binarios en la ‘flash’ para poder terminar haciendo lo mismo en un procesador super complejo. De ahi la gran aficion a chips como el PICAXE o Basic STAMP… En resumen sin darnos cuenta nos alejábamos definitivamente del concepto “Basic”.

La suerte y la buena noticia para todos los que sentimos pasión por estos artilugios que nos abstraen a esa mágica mezcla entre electrónica y lenguajes, es que a punto de pronunciar el tipico : “El Basic a Muerto” Viva el BASIC!!, vuelve a aparecer a escena la implementacion de «Visual Basic» para projectos del MicroFramework 4.2, que como sabeis solo estaba disponible para C# hasta la fecha. 

Que os parecería cacharrear utilizando visual studio y expresiones como las que siguen :

        While (True)
            Encender(Led_Azul)
            Esperar(1)
            Apagar(Led_Azul)
            Esperar(1)
            If "Expresion" = "Cierta" Then
                Encender(Alarma_1)
            Else
                Apagar(Alarma_1)
            End If
        End While

Uno de los avances mas importantes en este sentido, es la posibilidad de desarrollar y depurar aplicaciones con o sin electrónica, pues podemos crearnos nuestros propios dispositivos emuladores y en el mejor de los casos si disponemos del dispositivo físico podemos depurar directamente sobre la electrónica a traves del puerto serie o USB.

La proposición es fácil, bienvenidos al mundo de los apasionantes sistemas embebidos “on chip”, después de largos años de desarrollo .NET MicroFramework alcanza una madurez envidiable en su versión 4.2, convirtiéndose en un excelente ‘open source’ y como ya he dicho antes, incorporando por fin la posibilidad crear nuestros nuevos proyectos recuperando Visual Basic.

Me permito postearos esta sencilla introducción, como preámbulo a todo un apartado que nos puede dar mucho de que hablar, pues ciertamente muchos lectores de este blog siempre han mostrado especial interés en controlar dispositivos de una forma amigable. Esperando vuestros comentarios para ir dando formato a los futuros artículos.

Aquí tenéis el código completo para un hardware genérico. Creo que es muy interesante motivaros en la forma que podemos adaptar la redacción de nuestras funciones de una forma altamente inteligible.

Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
 
Public Module Principal
 
    Sub Main()
        While (True)
            Encender(Led_Azul)
            Esperar(1)
            Apagar(Led_Azul)
            Esperar(1)
            If "Expresion" = "Cierta" Then
                Encender(Alarma_1)
            Else
                Apagar(Alarma_1)
            End If
        End While
    End Sub
 
End Module
 
' Definicion de funciones
Module Funciones
    
    Sub Encender(pin As OutputPort)
        pin.Write(True)
    End Sub
 
    Sub Apagar(pin As OutputPort)
        pin.Write(False)
    End Sub
 
    Sub Esperar(segundos As Integer)
        Thread.Sleep(segundos * 1000)
    End Sub
End Module
 
' Constructores y definicion de nombres
Module GPIOs
    Public Led_Azul As OutputPort = New OutputPort(CType(55, Cpu.Pin), False)
    Public Alarma_1 As OutputPort = New OutputPort(CType(18, Cpu.Pin), False)
End Module

Que lo disfrutéis!
PepLluis,

MUTEX o Primitivas de sincronización.

Sin la intención de profundizar excesivamente y relativo a una pregunta relativa al control de la ejecución de varias instancias de una misma aplicación. Se me ocurre responder : Con el uso MUTEX!

Creo que vale la pena que ‘echéis’ un vistazo al código… reamente infalible!

            bool SingleInstance;
            Mutex mutex = new Mutex(false"MiCodigoMutex"out SingleInstance);
            if (!SingleInstance)
            {
                MessageBox.Show(null"No se puede ejecutar mas de una instancia"
"Programa en ejecucion"MessageBoxButtons.OK, MessageBoxIcon.Stop);                 this.Close();             }

Saludos navideños,
PepLluis,

El puerto Serie, como usarlo en WPF

Atendiendo el comentario de Jose Fco en el que indica :

<< He podido leer diversos ejemplos de como utilizar e implementar las funciones básicas de acceso al puerto serie principalmente en aplicaciones WinForms, seria posible obtener una esqueleto base en WPF tal como tienes para los anteriores.>>

El siguiente ejemplo, se entiende como ejercicio para realizar la transmisión y recepción de una trama utilizando un temporizador de un segundo en un proyecto WPF, para cerrar el circuito deberás insertar un conector en el puerto serie con un puente entre los pines 2 y 3. Recordad que el uso de ReadLine suspende la ejecucion del thread hasta recibir la sequencia definida en ‘SerialPort.NewLine’.

Partial Public Class Window1

    Delegate Sub Actualizar()     Private WithEvents Puerto1 As New System.IO.Ports.SerialPort     Private temporizador As New System.Timers.Timer     Private Recibidos As String = ""

    Sub New()         ' Llamada necesaria para el Diseñador de Windows Forms.          InitializeComponent()         Puerto1 = My.Computer.Ports.OpenSerialPort("COM1", 9600)         AddHandler Puerto1.DataReceived, AddressOf Recepcion         temporizador.Interval = 1000         temporizador.Enabled = True         AddHandler temporizador.Elapsed, AddressOf Peticion     End Sub
    Private Sub Recepcion()             Recibidos = Puerto1.ReadLine             Me.Dispatcher.Invoke(New Actualizar(AddressOf Datos))     End Sub
    Sub Peticion()             Puerto1.WriteLine("Saludos!")     End Sub
    Sub Datos()             Me.Label1.Content = Recibidos     End Sub End Class

Espero que cumpla con tus espectativas.
Saludos,
PepLluis,

Como declarar el puerto serie de forma Global

Respondiendo una pregunta de los foros, me complace compartir con vosotros el siguiente ejercicio; no sin antes puntualizar que se trata de la puesta en escena de un ejemplo que utilizaría un modulo como “clase estática” donde depositar objetos compartidos dentro de nuestro espacio de aplicación.

Para evitar interpretaciones, este es uno de esos ejemplos que no debe considerarse “modelo” pues su escenario es poco menos que atípico, aclarar que en situaciones similares lo adecuado seria diseñar una clase completa con toda la funcionalidad y acceso, para posteriormente incluirla como propiedad en un modulo. La dificultad se encuentra en la cantidad de código que deberíamos desplegar para realizar una explicación que finalmente terminaría siendo compleja de seguir y entender.

Dicho esto, el siguiente es solo un punto de entrada para las personas que intentan iniciarse en el tema y se encuentran en situaciones como la que expone “Caudiz” en los foros… necesita poder acceder al puerto serie desde dos forms diferentes.

Primero definiríamos el modulo que contendrá toda la lógica de acceso al puerto serie y podría ser algo similar a lo que sigue :

Imports System.IO.Ports
 
Module SerialComm
 
    Private SerialPort1 As New SerialPort
    Private LastFrameRead As String
 
    Public Event DataAvailable()
 
    Sub New()
        SerialPort1.PortName = "COMx"
        SerialPort1.Open()
        AddHandler SerialPort1.DataReceived, AddressOf ReceiveData
    End Sub
 
    Private Sub ReceiveData()
        LastFrameRead += SerialPort1.ReadExisting.ToString()
        RaiseEvent DataAvailable()
    End Sub
 
    Public Function ReadData() As String
        Return LastFrameRead
    End Function
 
    Public Sub WriteData(Frame)
        SerialPort1.Write(Frame)
    End Sub
 
    Public Sub ClearData()
        LastFrameRead = ""
    End Sub
 
End Module

Finalmente incluiríamos el siguiente código para acceder a dicha funcionalidad en este caso desde el ‘Form1’ aunque evidentemente podemos incluirlo desde cualquier otro punto del espacio de nuestra aplicación.

Public Class Form1
 
    Sub Form1_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        AddHandler SerialComm.DataAvailable, AddressOf ReadData
        Form2.Show()
    End Sub
 
    Sub ReadData()
        Me.Label1.Text = SerialComm.ReadData
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgsHandles Button1.Click
        SerialComm.WriteData("Hola :-) from 1")
    End Sub
End Class
Public Class Form2
 
    Private Sub Form2_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        AddHandler SerialComm.DataAvailable, AddressOf ReadData
    End Sub
 
    Sub ReadData()
        Me.Label1.Text = SerialComm.ReadData
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgsHandles Button1.Click
        SerialComm.WriteData("Hola :-) from 2")
    End Sub
 
End Class

Espero vuestros comentarios y que a partir de esta idea, podáis construir de forma robusta la implementación de vuestra solucion.
Saludos,
PepLluis,

El servicio no autenticó al autor de la llamada.

Supongo que como “Tips and Tricks” por pregunta recurrente, cuando intentamos implementar un Servicio “WCF” en nuestro servidor, después de haberlo probado repetidamente en nuestro equipo de desarrollo sin ningún tipo de incidencia…

A tu PREGUNTA (Pablo):
Cuando intento conectarme al servicio desplegado en mi servidor, después de haber pasado las pruebas en nuestro entorno de desarrollo, recibo el siguiente mensaje : "El servicio no autenticó al autor de la llamada”, pero en mi caso no me interesa ningún tipo de autenticación para poder acceder al servicio, como debo configurar el cliente?.

La RESPUESTA:

A banda de que en este caso concreto no te interese implementar ningún tipo de autenticación es casi obligado que leas las recomendaciones sobre la arquitectura de seguridad para WCF en .NET Framework 4.0, este es el link : http://msdn.microsoft.com/es-es/library/ms788756.aspx

En tu caso el mensaje te esta indicando que tu servicio web esta implementando un “wsHttpBinding”, Si lo que te interesa es un acceso “Básico” para entendernos como con los antiguos “ws”, entonces debes editar el archivo de configuración del host “web.config” donde tengas instalado el servicio, y modificar del <System.ServiceModel> el <endpoint address="" binding="wsHttpBinding" contract="TusServicios.IService1"> por :

binding="basicHttpBinding" … con ‘b’ minúscula 🙂

Luego es muy importante que actualices las referencias a tu servicio, pues en caso contrario el cliente se responderá con una excepción :

“No se pudo activar el servicio solicitado”… es obvio por la discordancia, desde el explorador de soluciones, click en el servicio y seleccionas la opción

– Actualizar referencia de Servicio

y Listo.

Saludos,
PepLluis,

Roslyn – El fin de las cajas negras.

Es curioso cómo puede variar el significado de las palabras… al oír este nombre en código, no puedo evitar visualizar imágenes de mi juventud, en concreto cuando los hombres del campo se acercaban al bar para robarle un respiro al día y apoyándose en la barra pedían a voces “un café” “una Copa” y un “Rosly’n” gesticulando transcendentalmente… jajaja, No sé si por casualidad o coincidencia todos los machotes que practicaron esa poco saludable costumbre, terminaron como los compiladores… con las cajas torácicas bien negras.

Dicho esto, parece ser que el término se invierte y ahora “Roslyn” representara el fin de tres décadas de cajas negras invocando los prompt’s de un misterioso mago escondido tras un ejecutable llamado compilador.

Este es otro de esos excitantes puntos de inflación en los lenguajes, a pesar de los “roadmap” de producto, evoluciones y tecnologías que Visual Studio va incorporando a la plataforma, sin duda este paso me recuerda a un nuevo hito que cambiara nuestro concepto a la par que lo hizo Linq en su momento. Por lo tanto “Bienvenido Roslyn”

¿Pero qué es Roslyn?

Es la posibilidad de utilizar los compiladores de C# y Visual Basic invocándolos en un modelo de servicios. Lo se una respuesta simple, difícil de asimilar.

Durante muchos años cientos de programadores han estado reclamando la posibilidad de disponer de “compiladores dinámicos” a los que poder invocar sin necesidad de llamar complejos ‘scripts’ dentro o fuera del propio entorno de programación.

Anders Hejlsberg, dio una charla sobre el futuro C# y Visual Basic en el pasado BUILD, os dejo el enlace por si acaso: http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-816T

Os aconsejo descargaros la CTP de octubre 2011, es divertidísimo trastear con ella, además tendrás acceso a un montón de ‘Walkthrough’ entre los cuales encontraras el proyecto para generarte la extensión que te permitirá jugar a ser Anders, copiando código entre dos proyectos distintos; uno en VB y pegando en C#, poco menos que genial!!

Para ello solo tenéis que compilar el proyecto “ConvertingPasteExtensions” incluido en el CTP y luego instalar la extensión generada en Visual Studio… una vez completado, podrás disponer del genial “Paste as C#” o “Paste as Visual Basic”.

Aunque es este sentido, la implementación no está realizada al completo, deberéis tener paciencia pues no todas las expresiones “sobre todo Linq” funcionaran de un lado a otro… pero como digo, eso no quita las ganas de empezar a inventar descubriendo el montón de nuevas posibilidades que “Roslyn” nos podrá al descubierto.

Puedes descargarte la CTP desde: http://msdn.microsoft.com/es-es/roslyn

Que lo disfrutéis!,
PepLluis,

About read values of received data (Complete code for last post)

Atendiendo la petición de un lector pidiéndome el código completo…

Public Class Form1
    ''' <summary>
    ''' Complete code to test the frame reading values sample (last post)
    ''' PepLluis, 11/10/2011
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        ' Simulate string frame with values
        Dim frame = "{W111}{M222}{F333}{S444}"
        ' define Label and textboxes
        Dim Label1 As New Label With
            {.Name = "Label1", .AutoSize = True, .Location = New Drawing.Point(12, 10), .Text = "Frame :" + frame}
        Dim TextBox1 As New TextBox With {.Name = "TextBox1", .Width = 60, .Location = New Drawing.Point(12, 30)}
        Dim TextBox2 As New TextBox With {.Name = "TextBox2", .Width = 60, .Location = New Drawing.Point(12, 50)}
        Dim TextBox3 As New TextBox With {.Name = "TextBox3", .Width = 60, .Location = New Drawing.Point(12, 70)}
        Dim TextBox4 As New TextBox With {.Name = "TextBox4", .Width = 60, .Location = New Drawing.Point(12, 90)}
        ' add controls to form
        Me.Controls.AddRange({Label1, TextBox1, TextBox2, TextBox3, TextBox4})
        ' define char as fields separators and values iden
        Dim separators As Char() = {"{""W""M""S""F""}"}
        ' get fields
        Dim fields As String() = (
              From f As String In frame.Split(separators)
              Where f.Length > 0
            ).ToArray
        ' get textBoxes names
        Dim textBoxesNames() =
            (
                From Tbn As Object In Me.Controls
                Where Tbn.GetType.Name = "TextBox"
                Select CType(Tbn, TextBox).Name Order By Name
            ).ToArray
        ' assign values to textboxes
        For Index As Integer = 0 To textBoxesNames.Count - 1
            Me.Controls.Item(textBoxesNames(Index)).Text = fields(Index)
        Next
    End Sub
End Class

 

Regards! :-)  
PepLluis,

Easy or difficult, does not matter for VB or C# if you build your style

 

Pregunta:

Perdido en la recepción de datos.

A menudo recibo vuestras preguntas pidiéndome si os puedo aportar alguna idea para resolver casuísticas concretas. Lamentablemente por falta de tiempo no siempre puedo dedicar un post a cada una de vuestras inquietudes, sin embargo en ocasiones se plantean situaciones que se repiten y en caso de resolverlas considero que pueden ayudar a más personas con la misma inquietud y creo que este es el caso :

Pedro me escribe con lo siguiente: <Estoy encallado en un punto del cual me está costando salir… tengo un hardware especifico por el que el puerto serie me envía una trama conteniendo la información de varios valores separados por unos delimitadores>

La pregunta es: Como puedo detectar cuando recibo los indicadores, como distingo la letra que identifica el dato y finalmente como puedo leer únicamente su valor y colocarlo en un textbox. 

 Question :

I’m lost receiving RS232 data.

I often get questions asking me if I can contribute with any idea to solve concrete cases. Unfortunately due to lack of time I cannot always devote a post to each of your concerns, however sometimes there are situations that are repeated in case of solving them believe that they can help more people with the same concern and provably that may be the case:

Peter write me with the next question : < I am aground at a point which is costing me leave; I have an specific hardware with a serial port, that port sends me a frame containing information from several values separated by a few delimiters>

The question is: How I can detect the indicators positions, and how I can distinguish the letter that identifies the data and finally how can read only its value and send this to a textbox.

 

 Visual basic = 

Public Class Form1
 
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        Dim frame = "{W111}{M22}{F33}{S44}"
        Dim separators As Char() = {"{""W""M""S""F""}"}
        Dim fields As String() = (From f As String In frame.Split(separators) Where f.Length > 0).ToArray
        Dim textBoxesNames() = (From Tbn As Object In Me.Controls Where Tbn.GetType.Name = "TextBox" Select CType(Tbn, TextBox).Name Order By Name).ToArray
        For Index As Integer = 0 To textBoxesNames.Count - 1
            Me.Controls.Item(textBoxesNames(Index)).Text = fields(Index)
        Next
    End Sub
End Class

C# =

using System;
using System.Linq;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            string frame = "{W111}{M22}{F33}{S44}";
            char[] separators = new char[] { '{''W''M''S''F''}' };
            string[] fields = (from string f in frame.Split(separators) where f.Length > 0 select f).ToArray();
            string[] textBoxesNames = (from Tbn in this.Controls.OfType<TextBox>() where Tbn.GetType().Name == "TextBox" orderby Tbn.Name select Tbn.Name).ToArray();
            for (int Index = 0; Index < textBoxesNames.Count(); Index++)
            {
                this.Controls[textBoxesNames[Index]].Text = fields[Index];
            }
        }
    }
}

Regards,
PepLluis,

Autoincrementar el “Assembly Version” de nuestro proyecto.

A propósito de mi último post, mi encuentro con el equipo de tres desarrolladores propicio una discusión en torno a cómo controlar el número de versión de cada proyecto, después de discutir llano y largo lo oportuno de realizar estas tareas de una manera centralizada desde los gestores de “Control de Código” y dando por imposible entenderlo de otra forma, se me planteo el reto de cómo poder incrementar el número de versión del ensamblado del proyecto desde el propio código del proyecto de forma automática y en función a si se estaba haciendo un ‘debug’ o un ‘release’.

Evidentemente el siguiente código, muestra y demuestra que es posible aunque debo rehuir de cualquier otra interpretación para tales prácticas, pues creo que es evidente que salvo excepciones no pueden ser tomadas más que como un ejercicio “curioso”.

using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
 
namespace VersionString
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            SetNewVersion();
            LblVersion.Text = Application.ProductVersion.ToString();
        }
 
        private void SetNewVersion()
        {
            try
            {
                string AssemblyFile = @"..\..\Properties\AssemblyInfo.cs";
                string str = System.IO.File.ReadAllText(AssemblyFile);
                Regex r = new Regex(@"\[assembly\: AssemblyVersion\(""(\d{1,})\.(\d{1,})\.(\d{1,})\.(\d{1,})""\)\]");
                Match m = r.Match(str);
 
                string rz = string.Format("[assembly: {4}(\"{0}.{1}.{2}.{3}\")]"
                    , m.Groups[1].Value
                    , m.Groups[2].Value
                    , m.Groups[3].Value
                    , Convert.ToString((Convert.ToInt16(m.Groups[4].Value))+1)
                    , "AssemblyVersion");
                System.IO.File.WriteAllText(AssemblyFile, r.Replace(str, rz));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
 
}

A falta de convencer al equipo para que se animen a utilizar algunos de los excelentes gestores de código para visual studio, aquí va mi dedicatoria… a demás con el código reclamo esa ronda de cervezas. J
PepLluis,

Visual Studio, Añadir como Vinculo y con cariño

Tengo la suerte de poder compartir conocimientos con una gran diversidad de profesionales y entre ellos con un nutrido grupo de desarrolladores. En este sentido a menudo soy espectador de cómo somos víctimas de nuestra propia sinergia y obviamente a menudo nos vemos sorprendidos por utilizar o adoptar técnicas incorrectas simplemente porque así lo hicimos o mal entendimos desde el principio. Me encanta compartir esto con vosotros, pues son historias que algunas veces ponen al descubierto las mas retorcidas formas de interpretar la tecnología en nuestro “aburrido” día a día… para los que no quieren convertirlo en “divertido”.

Intentare abreviar e ir al grano pero creo que será difícil, os explicare que se trata de la forma en que gestionamos nuestros proyectos, si bien en equipos organizados el propio control de código nos ofrece herramientas suficientemente sofisticadas para evitar las malas prácticas, conduciéndonos y aplicándonos metodologías sobradamente contrastadas; existe aún un gran grueso de pequeños equipos de desarrolladores que “a su bola” realizan su trabajo en un frenético pulso por sacarse las tareas de encima sin reparar en las graves consecuencias a nivel de costes horarios cuando dejan de ocupar su puesto de trabajo.

Dicho esto, la semana pasada recibí una llamada de un buen colega, pidiéndome soporte para averiguar si podíamos entender unos inexplicables problemas con alguno de los proyectos que un antiguo empleado había liderado y al parecer era un problema de gran magnitud.. Por supuesto mi interés en entender tal misterio fue tan poderoso que no tarde ni una hora en acudir.

Recordad: Los grandes problemas se resuelven con pequeñas soluciones 🙂

Se trataba de un equipo de tres desarrolladores, creando sus proyectos en un recurso compartido “mal hecho!”, cada uno gestionando su parcela “el colmo!” y para rematarlo algunas librerías y proyectos eran base para compartir “peor imposible!” , puede parecer irreal pero os aseguro que es real y esta situación se produce en mas ocasiones de las que podemos imaginarnos.

El problema radicaba en que ciertos proyectos parecían no compilarse adecuadamente o que las referencias a ciertas partes en común no terminaban de contener la totalidad de las funciones diseñadas. Ummm… ciertamente extraño.

Al dar un vistazo por alguno de los proyectos base, pude observar que se compilaban como parte de la solución, sin embargo en otros proyectos más simples en vez de crear una solución conteniendo los distintos proyectos, se hacía referencia a clases que estaban ubicadas en “ese recurso compartido”, cuál fue mi sorpresa al observar que el antiguo empleado, cuando necesitaba alguna clase base para su proyecto… simplemente la añadía al proyecto! Sin atinar que cuando simplemente utilizas la opción de “Agregar Elemento Existente” en el explorador de Visual Studio lo que estás haciendo es una copia del “archivo en cuestión” a la ubicación de tu proyecto, por lo tanto cuantas modificaciones sobre el mismo serán para ese proyecto y no del origen del mismo.

Después de investigar algunos de los proyectos en los que “el antiguo empleado” había trabajado, nos quedo un rastro de algunas decenas de clases con el mismo nombre en diferentes proyectos y por supuesto diferentes contenidos, supongo que dicha persona nunca llego a entender lo que realmente estaba haciendo, pues en otro caso debo pensar que fue negligencia total.

Salvando las distancias quiero pensar, que en algún punto del camino cuando este profesional aprendía como utilizar las herramientas, no presto suficiente atención para entender que existen dos formas distintas para añadir un “elemento Existente”… está claro que el escenario de una clase compartida en un recurso compartido la opción correcta no es “Agregar”, si no “Agregar como Vinculo” solo debería haber prestado un poquito de atención en el combo que ofrece las opciones de agregar, supongo que ello hubiera ahorrado un montón de angustias.

Finalmente y a titulo de reflexión, tal y como empecé diciendo me gustaría pensar que somos víctimas de nuestras propias sinergias y desgraciadamente no atinamos en ellas hasta que alguien atina a explicarlas. Bien para que no quede en entredicho, si por alguna de aquellas casualidades alguien más desconoce este matiz, estar encantando de haber sido útil.

Recordad: Los detalles más insignificantes son los que causan los problemas más graves! 🙂

IMPORTANTE: La version “Basic” de Team Fundation es gratis!… que excusa tienes ahora?

Saludos,
PepLluis,