Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#3681
Cita de: kub0x en 14 Mayo 2016, 06:33 AMhttps://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx (con esto se arregla ;) )

El compañero @KuBox ya te ha dado y explicado la solución, particionar la lógica del algoritmo en bloques de método individuales es irse por las ramas, ya que sigues sin evaluar la propiedad que se te mencionó.

Pero aparte del uso de la propiedad Control.Invoke, es muy recomendable que también utilices la propiedad Control.InvokeRequired para evitar intentar invocar el control de forma síncrona en caso de que haya sido creado desde el mismo hilo, ya que de lo contrario esto ocasionaría comportamientos indeseados y/o errores, como por ejemplo la recreación del handle del control;

También hay otros controles de errores adicionales que serían bastante imprescindibles como por ejemplo:
· Utilizar la declaración SyncLock para evitar que múltiples hilos intenten modificar el control, por ejemplo si instancias e inicias el mismo BackGroundWorker 2 veces al mismo tiempo.
· Comprobar si los recursos del control fueron liberados (Control.IsDisposed).
· Comprobar si el handle de la ventana se creó, y verificarlo antes de llamar a Control.InvokeRequired, ya que de lo contrario Control.InvokeRequired siempre devolverá False indiferentemente del hilo donde se creó el control.

...Pero por el momento podemos dejarlo con la medida de seguridad básica y principal, que sería, como ya he dicho, evaluar el valor devuelto por Control.InvokeRequired.

Este sería el código que puedes utilizar:
Código (vbnet) [Seleccionar]
Imports System.Threading

Public NotInheritable Class Work : Implements IDisposable

#Region " Private Fields "

   <EditorBrowsable(EditorBrowsableState.Never)>
   Friend WithEvents Bgw As BackgroundWorker

   Private ReadOnly mreSync As ManualResetEvent
   Private ReadOnly mreAsync As ManualResetEvent

   Private isRunSync As Boolean = False
   Private isCancelSyncRequested As Boolean = False
   Private isPauseRequested As Boolean = False

#End Region

#Region " Properties "

   <EditorBrowsable(EditorBrowsableState.Always)>
   Public ReadOnly Property IsRunning As Boolean
       Get
           Return (Me.Bgw IsNot Nothing) AndAlso Not (Me.isPausedB)
       End Get
   End Property

   <EditorBrowsable(EditorBrowsableState.Always)>
   Public ReadOnly Property IsPaused As Boolean
       Get
           Return (Me.Bgw IsNot Nothing) AndAlso (Me.isPausedB)
       End Get
   End Property
   Private isPausedB As Boolean = False

   Public ReadOnly Property IsDisposed As Boolean
       <DebuggerStepThrough>
       Get
           Return (Me.Bgw Is Nothing)
       End Get
   End Property

#End Region

#Region " Constructors "

   <DebuggerNonUserCode>
   Public Sub New()

       Me.Bgw = New BackgroundWorker()
       Me.mreSync = New ManualResetEvent(initialState:=False)
       Me.mreAsync = New ManualResetEvent(initialState:=True)

   End Sub

#End Region

#Region " Public Methods "

   <DebuggerStepThrough>
   Public Sub Run()

       If Not (Me.IsDisposed) AndAlso Not (Me.Bgw.IsBusy) Then
           Me.isRunSync = True
           With Me.Bgw
               .WorkerSupportsCancellation = False
               .WorkerReportsProgress = False
               .RunWorkerAsync()
           End With
           Me.mreSync.WaitOne()

       Else
           Throw New InvalidOperationException("BackGroundWorker is already running.")

       End If

   End Sub

   <DebuggerStepThrough>
   Public Sub RunAsync()

       If Not (Me.IsDisposed) AndAlso Not (Me.Bgw.IsBusy) Then
           With Me.Bgw
               .WorkerSupportsCancellation = True
               .WorkerReportsProgress = True
               .RunWorkerAsync()
           End With

       Else
           Throw New InvalidOperationException("BackGroundWorker is already running.")

       End If

   End Sub

   <DebuggerStepThrough>
   Public Sub Pause()

       If Not (Me.IsDisposed) AndAlso Not (Me.isPausedB) Then
           Me.isPauseRequested = True
           Me.isPausedB = True
           Me.mreAsync.Reset()

       Else
           Throw New InvalidOperationException("BackGroundWorker is not running.")

       End If

   End Sub

   <DebuggerStepThrough>
   Public Sub [Resume]()

       If Not (Me.IsDisposed) AndAlso (Me.isPausedB) Then
           Me.isPausedB = False
           Me.isPauseRequested = False
           Me.mreAsync.Set()

       Else
           Throw New InvalidOperationException("BackGroundWorker is not paused.")

       End If

   End Sub

   <DebuggerStepThrough>
   Public Sub Cancel(Optional ByVal throwOnError As Boolean = False)

       Me.isCancelSyncRequested = True
       Me.CancelAsync()
       Me.mreSync.WaitOne()
       Me.isCancelSyncRequested = False

   End Sub

   <DebuggerStepThrough>
   Public Sub CancelAsync(Optional ByVal throwOnError As Boolean = False)

       If Not (Me.IsDisposed) AndAlso Not (Me.Bgw.CancellationPending) AndAlso (Me.Bgw.IsBusy) Then
           Me.mreAsync.Set() ' Resume thread if it is paused.
           Me.Bgw.CancelAsync()

       Else
           Throw New InvalidOperationException("BackGroundWorker is not initialized.")

       End If

   End Sub

#End Region

#Region " Private Methods "

   <DebuggerStepThrough>
   Private Function AddLvItem(ByVal src As ListView, ByVal dst As ListView, ByVal index As Integer) As ListViewItem

       Dim result As ListViewItem = Nothing

       If (dst.InvokeRequired) Then
           dst.Invoke(
               Sub()
                   Try
                       result = dst.Items.Add(src.Items(index).Text)
                   Catch ex As Exception
                       Debug.WriteLine(String.Format("Woker exception occured: {0}", ex.Message))
                   End Try
               End Sub)
       Else
           Try
               result = dst.Items.Add(src.Items(index).Text)
           Catch ex As Exception
               Debug.WriteLine(String.Format("Woker exception occured: {0}", ex.Message))
           End Try

       End If

       Return result

   End Function

#End Region

#Region " Event-Handlers "

   <DebuggerStepperBoundary>
   Private Sub MyWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
   Handles Bgw.DoWork

       Dim lock As Object = ""
       SyncLock lock

           Dim lv1 As ListView = WindowsApplication1.Form1.ListView1
           Dim lv2 As ListView = WindowsApplication1.Form1.ListView2
           Dim max As Integer = lv2.Items.Count
           Dim itemIndex As Integer = -1

           For i As Integer = 0 To (max - 1)

               If (Me.Bgw.CancellationPending) Then
                   e.Cancel = True
                   Exit For

               Else
                   If Me.isPauseRequested Then ' Pause this thread.
                       Me.mreAsync.WaitOne(Timeout.Infinite)
                   End If

                   Dim lvi As ListViewItem = Me.AddLvItem(src:=lv2, dst:=lv1, index:=Interlocked.Increment(itemIndex))
                   If (lvi IsNot Nothing) Then
                       Debug.WriteLine(String.Format("ListViewItem Text: {0}", lvi.Text))
                   End If

                   If Me.Bgw.WorkerReportsProgress Then
                       Me.Bgw.ReportProgress((i + 1) * (100 \ max))
                   End If

                   Thread.Sleep(TimeSpan.FromSeconds(1))

               End If

           Next i

       End SyncLock

       If (Me.Bgw.WorkerReportsProgress) AndAlso Not (Me.Bgw.CancellationPending) Then
           Me.Bgw.ReportProgress(100)
       End If

       If (Me.isRunSync) OrElse (Me.isCancelSyncRequested) Then
           Me.mreSync.Set()
       End If

   End Sub

   <DebuggerStepperBoundary>
   Private Sub Bgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
   Handles Bgw.ProgressChanged

       Debug.WriteLine(String.Format("Work Progress: {0:00.00}%", e.ProgressPercentage))

   End Sub

   <DebuggerStepperBoundary>
   Private Sub Bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
   Handles Bgw.RunWorkerCompleted

       If (e.Cancelled) Then
           Debug.WriteLine("Work state: Cancelled")

       ElseIf (e.Error IsNot Nothing) Then
           Debug.WriteLine("Work state: Error")

       Else
           Debug.WriteLine("Work state: Success")

       End If

       Me.Dispose()

   End Sub

#End Region

#Region " IDisposable Implementation "

   Private isDisposedB As Boolean

   <DebuggerStepThrough>
   Public Sub Dispose() Implements IDisposable.Dispose

       Me.Dispose(isDisposing:=True)
       GC.SuppressFinalize(obj:=Me)

   End Sub

   <DebuggerStepThrough>
   Private Sub Dispose(ByVal isDisposing As Boolean)

       If (Not Me.isDisposedB) AndAlso (isDisposing) Then
           Me.Bgw.Dispose()
           Me.Bgw = Nothing

           With Me.mreSync
               .SafeWaitHandle.Close()
               .SafeWaitHandle.Dispose()
               .Close()
               .Dispose()
           End With

           With Me.mreAsync
               .SafeWaitHandle.Close()
               .SafeWaitHandle.Dispose()
               .Close()
               .Dispose()
           End With

       End If

       Me.isDisposedB = True

   End Sub

#End Region

#Region " Hidden Methods "

   <EditorBrowsable(EditorBrowsableState.Never)>
   <DebuggerNonUserCode>
   Public Shadows Function GetHashCode() As Integer
       Return MyBase.GetHashCode
   End Function

   <EditorBrowsable(EditorBrowsableState.Never)>
   <DebuggerNonUserCode>
   Public Shadows Function [GetType]() As Type
       Return MyBase.GetType
   End Function

   <EditorBrowsable(EditorBrowsableState.Never)>
   <DebuggerNonUserCode>
   Public Shadows Function Equals(ByVal obj As Object) As Boolean
       Return MyBase.Equals(obj)
   End Function

   <EditorBrowsable(EditorBrowsableState.Never)>
   <DebuggerNonUserCode>
   Public Shadows Function ToString() As String
       Return MyBase.ToString
   End Function

#End Region

End Class


Ejemplo de uso:
Código (vbnet) [Seleccionar]
Public NotInheritable Class Form1 : Inherits Form

   Friend MyWork As Work

   Private Sub Button1_Click() Handles Button1.Click

       If (Me.MyWork IsNot Nothing) Then
           Me.MyWork.Cancel()
       End If

       Me.MyWork = New Work
       Me.MyWork.RunAsync()

   End Sub

End Class


Como se puede ver, la clase donde encapsulo el BackGroundWorker tiene varias funcionalidades añadidas para controlar operaciones sincrónicas y asincrónicas, si quieres ver la implementación completa y original, y con la documentación XML, aquí lo tienes:


Saludos.
#3682
Cita de: EagleStrike en 14 Mayo 2016, 03:16 AM
Bueno, gracias por la ayuda de todas maneras.
En realidad uso batch para hacer estas cosas complicadísimas sólo por eso, porque es limitado.

Igual, creo que tengo otra manera de hacer el proyecto. Esto de comunicar los mensajes sólo lo necesito para hacer más facil la parte de añadir expresiones a los "bots", de manera que las expresiones quedaran escritas en un archivo cmd aparte y no en el intérprete.

Si lo logro entender y terminar el proyecto lo subo!

Ahora que has mencionado el archivo de texto ...claro, una posible manera de comunicarse en Batch sería mediante el uso de un archivo local que haga de intermediario, ya que desde ambas instancias de la CMD puedes escribir en el mismo archivo, y desde ambas puedes leer lo que la otra instancia escribió (al final del archivo), y para saber con certeza si una de las dos instancias "intenta comunicarse" solo tendrías que comprobar si el tamaño del archivo es distinto al tamaño de la ultima vez que lo comprobaste (o comprobar la cantidad de lineas), en un búcle FOR con iteraciones indefinidas (por ejemplo).

Eso me parece una idea simple y efectiva, pero ahora también se me ocurre que tal vez podrías comunicarte mediante Telnet, aunque sin saber muy bien como es la "estructura" de ese script o esos scripts no se muy bien que decirte.

Saludos
#3683
La persona que escribió la respuesta que has citado de StackOverflow, se refiere a que al final ha acabado trasladando el código de C# a un nuevo proyecto de VC++ (escrito en modo no administrado).

¿Qué cuales cambios necesitarías hacer?, pues exactamente lo mismo que hizo esa persona, si quieres usar la API de UI Automation cambia de lenguaje para desarrollarlo en C++ importando los headers que se especifican en la referencia de la API de UI Automation (aquí), por que la otra opción sería perder unas semanas, un mes, o varios meses de tu vida en definir una infinidad de P/Invokes y wrappers en C#/VB.NET (e investigar y testearlos), lo que aparte de acabar logrando ser un código con probable inestabilidad (lo insuficientemente controlado), no es muy viable perder el tiempo de esa manera que digamos.

Como esa persona dijo, la herramienta de Microsoft UI Inspect está desarrollada en VC++, sin embargo tu estás bajo VB.NET o C#, y por ese motivo, cuando puedes usar lo mismo en un lenguaje que ya conoces, me parece una tontería pensar en hacer lo contrario, pero de todas formas si quieres probar a hacerlo mediante código no administrado entonces ya tienes un enlace a la API de UI Automation indicando, como ya he dicho, los headers de C++ y toda la información necesaria respecto a las definiciones.

No puedo ofrecerte una solución por que ni tan siquiera conozco la estructura de la UI que estás analizando, ni tengo el programa para testearlo, ni tampoco he pasado por el mismo problema que mencionas, lo siento, pero ten por seguro que debe existir una solución mediante código administrado, dudo mucho que las classes de .Net con los wrappers de UI Automation omitan elementos de la UI que al usar su equivalente desde la implementación "nativa" éstos no se omitan, eso suena demasiado extraño, así que desde la ignorancia yo simplemente creo que falta algo que añadirle a la ecuación (ej. una condición de búsqueda más especializada), pero que por el momento desconoces que factor hay que añadirle.

Saludos!.
#3684
Cita de: EagleStrike en 14 Mayo 2016, 01:45 AMCon lo que dijiste, Elektro, no tengo ni la menor idea de cómo hacer nada de lo que dijiste pero voy a investigar y hacer lo que pueda.

Batch es una herramienta muy limitada, no te molestes en seguir buscando, no se pueden aplicar las técnicas que mencioné. Puedes utilizar el parámetro SHARED del comando START para algo relacionado, pero su propósito de uso no tiene nada que ver con este propósito de comunicarse.




Las modificaciones en las variables de entorno solo tienen efecto para la instancia actual de la CMD y solo perduran durante el tiempo de vida de dicha instancia, sinceramen a mi no se me ocurre nada, lo siento.

Saludos!

#3685
Nuestro cerebro literálmente hablando es un ordenador biológico, desde el primer instante en el que estamos despiertos empieza a procesar todo tipo de datos sensoriales, los visuales, los auditivos, y etc., consumiendo así los recursos diarios limitados de nuestro procesador y el resto de componentes como la gráfica y nuestra tarjeta de memoria cerebral.

Las horas de sueño son necesarias para poner en un estado de hibernación o stand-by nuestro ordenador y así reducir el consumo de recursos al máximo, y entonces, se inician unas tareas programadas para almacenar lo que nuestra máquina consciente haya procesado durante el día (experiencia), filtrar y excluir datos innecesarios (evolución), hacer un backup de lo que nos pueda servir (recuerdos), y evaluar todo tipo de condiciones futuras en posibles escenarios de supervivencia (sueños y pesadillas).

Por muy ridículo o inasimilable que resulte, no se puede negar que todos los seres vivos con cerebro compartimos muchísimos aspectos similares comparándonos con el funcionamiento y limitaciones de un dispositivo informático como sería un PC, un smarthpone o una cámara, cosa que no podemos decir por ejempo de una una silla, un armario, o una pelota.

El ser humano hace mucho tiempo que empezó a intentar crear un ser corporeo y con vida a partir de recursos informáticos, los primeros intentos fueron conocidos como videojuegos (ej. 'Los Sims'), y ahora lo conocemos como robots con inteligencia artificial, implantes humanos artificiales, e incluso el nacimiento de animales clonados vivitos y coleando (ej. La oveja Dolly).

Así lo veo yo, solo es necesario tiempo y avances tecnológicos para que un dia no muy lejano acabar creando algo que podamos llamar "ser", seguido de "humano", y entonces toda la humanidad se tendrá que plantear la siguiente cuestión:

'¿Qué fue primero, el hombre, o la máquina?.'

...para acabar concluyendo, descubriendo y aceptar que somos exactamente lo mismo, solo que nosotros desconocemos quien nos creó o nos "programó" (no tiene por que ser un Dios omnipotente e incorporeo que vive en los cielos, no, pudo haber sido otro ser vivo el que nos dió la vida, como una especie de científicos extraterrestres, por así decirlo).

PD: Si el hombre ha usado la tecnología para diseñar el PC/robot a su imagen y semejanza, ¿quien dice que con la suficiente paciencia el hombre no pueda ser capaz de crear a otro hombre?.

Saludos!
#3686
¿No te estarás refiriendo más bien a comunicar dos aplicaciones command-line entre si? (por que si realmente hablamos de dos procesos 'cmd.exe' a los que no tienes ningún control...)

En ese caso puedes enviar y recibir cadenas de texto asignando un espacio de memoria compartida para ambos procesos, o también puedes hacerlo mediante un socket abierto, u otras técnicas de IPC.

Saludos
#3687
Cita de: engel lex en 12 Mayo 2016, 20:21 PM
empezemos por que es "imacros"? no es esto una pregunta del foro de mac osx?

iMacros es una aplicación multi plataforma para la automatización de navegadores y el testing a nivel web (typo WATIR o Selenium, te serán nombres más conocidas).

Yo lo tengo para Windows, pero hace muchísimo que no lo uso para nada.




Cita de: Boogie en 12 Mayo 2016, 18:29 PMSe puede impedir que imacros se actualice?

Asumiendo que iMacros no tenga ninguna opción para desactivar las actualizaciones automáticas, en MAC OSX no se como se logrará, pero en Windows podrías añadir un mapeo al archivo HOSTS de windows para denegar las actualizaciones programáticas de la aplicación, claro está que para ello primero deberás hacer un pequeño monitoreo con cualquier herramienta de análisis de conexiones establecidas por la aplicación (cuando éste demande la actualización automática) para descubrir la IP, y entonces poder añadirla al archivo HOSTS.

Otra opción más directa sería utilizar el Firewall de Windows para añadir una regla que deniegue todas las conexiones salientes, pero denegar todas las conexiones tal vez podría traer consecuencias negativas en el funcionamiento de la aplicación, depende de como trabaje el programa, siempre puedes hacerlo así y si ves que el programa da error o no va bien entonces deshaces la regla del Firewall.

Saludos
#3688
Cita de: nanoakb en 12 Mayo 2016, 15:08 PMsi tuvieras que recomendarme un lenguaje cual seria? aver si me pongo en ello

Para este tipo de tareas, algo sencillo a la vez que efectivo sería Visual Basic.NET (no confundir con VB6 ni VBS) o C#, en ambos lo harías de la misma manera pero utilizando una sintaxis distinta.

Con la función System.IO.Directory.GetFiles() puedes obtener los archivos, y de manera recursiva (o no).
Con las propiedades del type System.IO.FileInfo puedes obtener la fecha de creación, modificación o último acceso de un archivo.
Para la exclusión, una manera sencilla sería con una query de LINQ-to-objects (From fi As FileInfo In files Where Not (fi.CreationTime < DateTime.Today.AddDays(-15)), así de simple en una sola linea).

PD: Hasta para alguien que jamás haya tocado esos lenguajes creo que es muy sencillo si buscas ejemplos de los nombres que he mencionado en Google y lo intentas hacer, en serio.

Saludos!
#3689
Hola.

1:
La herramienta Spy++, aparte de poder considerarla obsoleta por su descontinuación de desarrollo o desactualización, está diseñada y enfocada para la inspección de ventanas Win32, y aquí surge el problema, por que una aplicación WPF no trabaja con el modelo de la API Win32/Win64, es una tecnología completamente diferente, sin embargo, el elemento de ventana principal de una aplicación WPF sigue exponiendo un handle de ventana (HWND) accesible mediante la class HwndWrapper, que sirve como contenedor de la WinAPI y WPF.

Como herramientas más modernas, completas y en constante actualización para inspeccionar ventanas Win32 y WPF, estas son mis recomendaciones:

  • XAML Spy
    Solamente para aplicaciones WPF.
    Tiene una interfáz de usuario muy amigable y bonita.
  • Microsoft UI Inspect
    Para aplicaciones Win32 y WPF.
    Lo puedes encontrar en el SDK de Windows para tu versión de Windows actual.




2:
Para identificar un elemento de una UI en WPF, generálmente no es necesario recurrir a la metodología que estás aplicando con la WinAPI, puedes evitar toda la tediosidad que supone la implementación y el uso inseguro de código no administrado con las típicas definiciones de las funciones que has mencionado de la lib. user32.dll para identificar elementos en la UI y etc...

En su lugar, puedes usar código administrado aprovechando el potencial del framework de Microsoft UI Automation, con los ensamblados de WPF (puedes utilizarlos desde windowsForms también, e incluso puedes utilizarlos para ventanas Win32 también, aunque todo esto dependerá siempre de ciertas circunstancias).

El uso de UI Automation resulta bastante sencillo, se basa en crear condiciones de búsqueda para hallar el elemento deseado, deberiamos saber lo que andamos buscando tras haber inspeccionado la aplicación con UI Inspect o nuestra herramienta favorita, pero si desconocemos lo que tenemos que buscar entonces siempre podemos iterar las ventanas y los árboles de controles para ir descubriendo la información como hariamos con el callback de la función EnumChildwindows y etc. para ventanas Win32.

Si creamos un nuevo proyecto WPF y le añadimos un LabelControl a la ventana principal, quedando así el código XAML:
Código (xml) [Seleccionar]
<Window x:Class="WpfApplication1.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:local="clr-namespace:WpfApplication1"
       mc:Ignorable="d"
       Title="Mi Ventana" Height="350" Width="525">
   <Grid>
       <Label Content="This is a Label control." />
   </Grid>
</Window>


Esto sería un ejemplo básico para identificar el label y obtener su texto en la aplicación compilada:
Código (vbnet) [Seleccionar]

Imports Windows
Imports Windows.Automation

...

Dim pid As Integer = Process.GetProcessesByName("WpfApplication1").Single().Id

Dim parentConditions As New OrCondition({
   New PropertyCondition(AutomationElement.ProcessIdProperty, pid, PropertyConditionFlags.None),
   New PropertyCondition(AutomationElement.NameProperty, "Mi Ventana", PropertyConditionFlags.IgnoreCase)
})

Dim labelConditions As New AndCondition({
   New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text, PropertyConditionFlags.None),
   New PropertyCondition(AutomationElement.RuntimeIdProperty, {7, 5924, 9119245}, PropertyConditionFlags.None)
})

Dim parentElement As AutomationElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, parentConditions)
Dim labelElement As AutomationElement = parentElement.FindFirst(TreeScope.Children, labelConditions)

If (labelElement IsNot Nothing) Then
   Dim labelText As String = labelElement.Current.Name
   Console.WriteLine(labelText)
End If


Nótese que en el código de arriba la condición de RuntimeIdProperty está hardcodeada, el label de tu aplicación tendrá otra Id asignada (lo puedes averiguar facilmente con UI Inspect, o en tiempo de ejecución con la función AutomationElement.GetRuntimeId) ...igual que el nombre del executable y el título de la ventana,
y dependiendo de la estructura de la aplicación seguramente debas añadir condiciones adicionales para identificar el espacio de trabajo y/o ventana donde se encuentre ese label.

Saludos.
#3690
Cita de: Lekim en 11 Mayo 2016, 18:11 PMDesde mi punto de vista en informática no existe nada "deprecado"

Eso es muy discutible, aunque cada persona puede interpretarlo como prefiera, pero lo que podemos ver es que en la vida, en la tecnología, y más concretamente en la informática, la utilización de lo deprecado tiende a traer consecuencias negativas (aparte de no estar aprovechando lo moderno/completo), como por ejemplo la ausencia de soporte y compatibilidad de lo que está deprecado, o que desaparezca por completo, cosa que también ocurre en la programación (si, las funciones deprecadas tienden a ser eliminadas con el paso de los años).

Sin ir más lejos te daré unos ejemplos que conoces de sobra:

  • Sistemas operativos como Windows XP y anteriores.
  • IDEs como Visual Studio 2010 y etc (que no soportan los nuevos runtimes de .Net Framework).
  • Visual Basic 5, 6, y etc.
  • La tecnología Windows Forms.
  • Los primeros runtimes de .NET Framework.

En lo que respecta al uso de funciones deprecadas en la API de Windows, cuando se le asigna el estado "deprecado", éstas tienden a desaparecer por completo con el tiempo como ya he mencionado, aunque comúnmente pasan a ser completamente reemplazadas por otras funciones más modernas, más completas, y en constante refactorización, mientras que esa función deprecada sigue permaneciendo ahí simplemente por compatibilidad y sin aportar ninguna mejora/refactorización en su código en el futuro, como por ejemplo la función WinExec. Como ya te digo, no es que yo me lo invente, también puedes leer lo que acabo de explicar, en la Wikipedia:

En resumen, lo obsolescente está condenado a la extinción por que la obsolescencia implica un olvido con el paso del tiempo, al menos así lo veo yo.




Cita de: Lekim en 11 Mayo 2016, 18:11 PMCreo que abusas de la palabra "deprecado" ya que te lo he visto usar muchas  veces.

Te equivocas, no creo que se pueda considerar abuso cuando la información que se da es la correcta para abrir camino hacia el uso de metodologías modernas.

Cuando me hayas visto decir que una función u otro tipo de miembro y/o conjunto o metodología está deprecada, jamás ni una sola vez lo he dicho como una simple opinión personal mia, sino como una información que está expuesta en los artículos de MSDN (o por desarrolladores de Microsoft en otros artículos, etc, vamos, cosas oficiales), no es que yo lo diga por que me de la gana, solamente transmito lo que afirma Microsoft con ese mismo termino "deprecated" ...seguido de un vínculo que redirige a una función y/o metodología mejorada, como suele ser, y como es el caso.




CitarNo estoy seguro que signifique lo que imaginas, ¿anticuado, desusado, viejo, arcaico, antiguo, desfasado, caduco, obsoleto?  

En inglés, deprecated significa obsoleto o censurado, pero en castellano he buscado y significa algo muy distinto como rogar o suplicar.

Vaya, ahí si que te tengo que dar toda la razón del mundo, he estado utilizando mal esa palabra todo este tiempo.

No me gusta decir que algo es obsoleto, no me gusta lo despectiva que suena esa palabra y por eso empecé a usar la palabra "deprecado" (dándole un significado incorrecto como has explicado) como sinónimo de anticuado, desfasado o ...si, obsoleto.




Citar
Cita de: Eleкtro en  9 Mayo 2016, 18:21 PMy un impacto negativo en el rendimiento de nuestra aplicación (iniciar un proceso y esperar el código de salida, consume mucho tiempo de ejecución en comparación)

Citar¿Qué computadora usas tú? Tanto como 'muucho tiempo' es exagerar. Yo no uso digamos una super computadora de la NASA, me considero una persona impaciente y a mí se me carga al instante aunque use Explorer.exe o Rundll32. En fin.

Que tu tengas la sensación de que se "cargue" al instante no significa que no exista una diferencia de velocidad por los procedimientos necesarios que supone crear un proceso y destuirlo. También se debe leer entre lineas cuando he dicho "es mucho EN COMPARACIÓN", eso en la mayoría de casos significa muy pocos millisegundos, no más, pero eso se puede considerar como una diferencia muy excesiva cuando se busca la perfección o eficiencia máxima posible de un algoritmo, por que esas pequeñas cosas (como por ejemplo búcles repetitivos que inicien executables para esperar un código de salida) son lo que al final lo acaban haciendo expensivo.




CitarEspero no te tomes estos comentarios como una reprimenda después de todo, tu también a veces lo haces XD

Si yo no estuviese abierto a las críticas negativas entonces no me consideraría moderador, y es cierto que yo a veces intento corregir a quien me parece o a quien estoy seguro de que se equivoca pero más que por corregirle es por enseñarle a esa persona, en cambio, me parece que tu en más de un comentario de este post has utilizado un sarcasmo extremo que no viene a cuento ...debido a ideas equívocas;
si no estás seguro de la veracidad de algo de lo que yo te diga, pues tal vez lo correcto sería preguntarme por que motivos afirmo esas cosas en vez de intentar corregir, o informarte por ti mismo para poder tener argumentos con los que debatirlo, y entonces yo aceptaría una posible corrección si hubiese que aceptarla.

Saludos!