elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Librería de Snippets para VB.NET !! (Compartan aquí sus snippets)
0 Usuarios y 2 Visitantes están viendo este tema.
Páginas: 1 ... 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [51] 52 53 54 55 56 57 58 59 60 Ir Abajo Respuesta Imprimir
Autor Tema: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets)  (Leído 526,933 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #500 en: 14 Marzo 2017, 21:29 pm »

No importa la versión de Visual Studio

En realidad si que importa. Cada nueva versión de Visual Studio añade modificaciones mejoradas en el empleo de sintaxis de C#/VB.NET. Dichas mejores evidentemente son incompatibles en versiones anteriores de Visual Studio.

Por ejemplo en VB.NET 14.0 (Visual Studio 2015) se pueden especificar strings multi linea lieterales, mientras que en las versioens anteriores de VB.NET, no.

VB.NET 14.0:
Código
  1.        Dim json = "{
  2.  'Name': 'Bad Boys',
  3.  'ReleaseDate': '1995-4-7T00:00:00',
  4.  'Genres': ['Action','Comedy']
  5. }"

El codigo de arriba daria error de compilación en versiones anteriores de VB.NET/VS. Habría que hacerlo más o menos así:
Código
  1.        Dim json = "{" & Environment.NewLine &
  2. "  'Name': 'Bad Boys'," & Environment.NewLine &
  3. "  'ReleaseDate': '1995-4-7T00:00:00'," & Environment.NewLine &
  4. "  'Genres': ['Action','Comedy']" & Environment.NewLine &
  5. "}"

Los snippets que compartí en este hilo fueron desarrollados bajo VS2013, y algunos en VS2015.

PD: Como ya dije, C# también tiene sus mejoras.

¡Saludos!


« Última modificación: 14 Marzo 2017, 21:35 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #501 en: 1 Abril 2017, 16:22 pm »

Hace mucho tiempo que no publico nada aquí...

Vamos allá:



¿Cómo validar el número de una tarjeta de crédito?

Para ello podemos implementar el algoritmo Luhn.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Uses the Luhn algorithm to determines whether the specified credit card number is valid.
  4. ''' <para></para>
  5. ''' Please de aware that not all valid credit cards can be verified with the Luhn algorithm because
  6. ''' it not covers all range of card numbers, however the Luhn algorithm does work for many, if not most, major credit cards.
  7. ''' <para></para>
  8. ''' The Luhn algorithm is simply used to prevent transpositional errors,
  9. ''' it is useful as a sanity check prior to submitting card numbers to a payment gateway,
  10. ''' but not suitable to absolutely validate whether a number is a valid card number.
  11. ''' <para></para>
  12. ''' The only way to absolutely verify a credit card number is to validate it via a payment gateway.
  13. ''' </summary>
  14. ''' ----------------------------------------------------------------------------------------------------
  15. ''' <remarks>
  16. ''' Luhn algorithm: <see href="https://en.wikipedia.org/wiki/Luhn_algorithm"/>
  17. ''' <para></para>
  18. ''' Microsoft's Luhn algorithm implementation: <see href="http://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/CreditCardAttribute.cs"/>
  19. ''' <para></para>
  20. ''' Credits to: <see href="http://www.vcskicks.com/credit-card-verification.php"/>
  21. ''' </remarks>
  22. ''' ----------------------------------------------------------------------------------------------------
  23. ''' <example> This is a code example.
  24. ''' <code>
  25. ''' Dim visaNumber As String = "4012888888881881"
  26. ''' Dim isValid As Boolean = ValidateCreditCardNumber(visaNumber)
  27. ''' </code>
  28. ''' </example>
  29. ''' ----------------------------------------------------------------------------------------------------
  30. ''' <param name="cardNumber">
  31. ''' The credit card number.
  32. ''' </param>
  33. ''' ----------------------------------------------------------------------------------------------------
  34. ''' <returns>
  35. ''' <see langword="True"/> if the specified card number is a valid card number; otherwise, <see langword="False"/>.
  36. ''' </returns>
  37. ''' ----------------------------------------------------------------------------------------------------
  38. Public Shared Function ValidateCreditCardNumber(ByVal cardNumber As String) As Boolean
  39.  
  40.    cardNumber = cardNumber.Replace(" ", "").Replace("-", "").Trim()
  41.  
  42.    ' FIRST STEP: Double each digit starting from the right
  43.    Dim doubledDigits As Integer() = New Integer(cardNumber.Length / 2 - 1) {}
  44.    Dim k As Integer = 0
  45.    For i As Integer = cardNumber.Length - 2 To 0 Step -2
  46.        Dim digit As Integer
  47.        If Not Integer.TryParse(cardNumber(i), digit) Then
  48.            Return False
  49.        End If
  50.        doubledDigits(k) = digit * 2
  51.        k += 1
  52.    Next i
  53.  
  54.    ' SECOND STEP: Add up separate digits
  55.    Dim total As Integer = 0
  56.    For Each i As Integer In doubledDigits
  57.        Dim number As String = i.ToString()
  58.        For j As Integer = 0 To (number.Length - 1)
  59.            total += Integer.Parse(number(j).ToString())
  60.        Next j
  61.    Next i
  62.  
  63.    ' THIRD STEP: Add up other digits
  64.    Dim total2 As Integer = 0
  65.    For i As Integer = cardNumber.Length - 1 To 0 Step -2
  66.        Dim digit As Integer = Integer.Parse(cardNumber(i).ToString())
  67.        total2 += digit
  68.    Next i
  69.  
  70.    ' FOURTH STEP: Total
  71.    Dim final As Integer = (total + total2)
  72.  
  73.    Return (final Mod 10 = 0) ' Well formed will divide evenly by 10.
  74.  
  75. End Function

Modo de empleo:
Código
  1. ' http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
  2. Dim visaNumber As String = "4012888888881881"
  3. Dim isValid As Boolean = ValidateCreditCardNumber(visaNumber)

Aquí les dejo unos números de tarjetas de crédito para testear:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Contains a collection of credit card numbers for testing purposes.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <remarks>
  7. ''' <see href="http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm"/>
  8. ''' </remarks>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <example> This is a code example.
  11. ''' <code>
  12. ''' For Each card As KeyValuePair(Of String, String()) In CreditCardsTestNumbers
  13. '''     For Each cardnumber As String In card.Value
  14. '''         Dim isValidNumber As Boolean = ValidateCreditCardNumber(cardnumber)
  15. '''         Console.WriteLine("Card type: '{0}'; Number: '{1}'; Is Valid?: {2}", card.Key, cardnumber, isValidNumber)
  16. '''     Next cardnumber
  17. ''' Next card
  18. ''' </code>
  19. ''' </example>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. Public Shared ReadOnly CreditCardsTestNumbers As New Dictionary(Of String, String())(StringComparison.OrdinalIgnoreCase) From {
  22.    {"American Express", {"378282246310005", "371449635398431"}},
  23.    {"American Express Corporate", {"378734493671000"}},
  24.    {"Australian BankCard", {"5610591081018250"}},
  25.    {"Dankort (PBS)", {"5019717010103742", "76009244561"}},
  26.    {"Diners Club", {"30569309025904", "38520000023237"}},
  27.    {"Discover", {"6011111111111117", "6011000990139424"}},
  28.    {"JCB", {"3530111333300000", "3566002020360505"}},
  29.    {"Mastercard", {"5555555555554444", "5105105105105100"}},
  30.    {"Switch/Solo (Paymentech)", {"6331101999990016"}},
  31.    {"VISA", {"4111111111111111", "4012888888881881", "4222222222222"}}
  32. }



¿Cómo auto-eliminar el executable de nuestra aplicación?

Para ello podemos escribir las instrucciones de eliminación en un archivo.bat externo, e iniciarlo.

¿Por qué Batch?, bueno, en un principio podriamos pensar en una solución usando puro código .NET por ejemplo compilando un código fuente en tiempo de ejecución para generar un executable de .NET temporal con las instrucciones de terminación del proceso y de eliminación del archivo, pero al hacer esto nos estaríamos metiendo en un círculo vicioso ya que el executable externo no se podría eliminar a si mismo, por ende, esta es una de las pocas ocasiones en las que Batch sirve para salvarnos de un apuro.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Deletes the self application executable file.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. Public Shared Sub DeleteSelfApplication()
  7.    DeleteSelfApplication(TimeSpan.FromMilliseconds(0))
  8. End Sub
  9.  
  10. ''' ----------------------------------------------------------------------------------------------------
  11. ''' <summary>
  12. ''' Deletes the self application executable file.
  13. ''' </summary>
  14. ''' ----------------------------------------------------------------------------------------------------
  15. ''' <param name="delay">
  16. ''' A delay interval to wait (asynchronously) before proceeding to automatic deletion.
  17. ''' </param>
  18. ''' ----------------------------------------------------------------------------------------------------
  19. Public Shared Async Sub DeleteSelfApplication(ByVal delay As TimeSpan)
  20.  
  21.    If (delay.TotalMilliseconds > 0.0R) Then
  22.        Dim t As New Task(Sub() Thread.Sleep(delay))
  23.        t.Start()
  24.        Await t
  25.    End If
  26.  
  27.    Dim script As String = <a>
  28. @Echo OFF
  29.  
  30. Set "exeName=%~nx1"
  31. Set "exePath=%~f1"
  32.  
  33. :KillProcessAndDeleteExe
  34. (TaskKill.exe /F /IM "%exeName%")1>NUL 2>&amp;1
  35. If NOT Exist "%exePath%" (GoTo :SelfDelete)
  36. (DEL /Q /F "%exePath%") || (GoTo :KillProcessAndDeleteExe)
  37.  
  38. :SelfDelete
  39. (DEL /Q /F "%~f0")
  40. </a>.Value
  41.  
  42.    Dim tmpFile As New FileInfo(Path.Combine(Path.GetTempPath, Path.GetTempFileName))
  43.    tmpFile.MoveTo(Path.Combine(tmpFile.DirectoryName, tmpFile.Name & ".cmd"))
  44.    tmpFile.Refresh()
  45.    File.WriteAllText(tmpFile.FullName, script, Encoding.Default)
  46.  
  47.    Using p As New Process()
  48.        With p.StartInfo
  49.            .FileName = tmpFile.FullName
  50.            .Arguments = String.Format(" ""{0}"" ", Application.ExecutablePath)
  51.            .WindowStyle = ProcessWindowStyle.Hidden
  52.            .CreateNoWindow = True
  53.        End With
  54.        p.Start()
  55.        p.WaitForExit(0)
  56.    End Using
  57.  
  58.    Environment.Exit(0)
  59.  
  60. End Sub

Modo de empleo:
Código
  1. ' Auto destruir el executable al instante:
  2. DeleteSelfApplication()
  3.  
  4. ' Auto destruir el executable de forma asincrónica con un tiempo de espera de 5 segundos:
  5. DeleteSelfApplication(TimeSpan.FromSeconds(5))

El contenido del archivo.bat generado sería el siguiente:
Código
  1. @Echo OFF
  2.  
  3. Set "exeName=%~nx1"
  4. Set "exePath=%~f1"
  5.  
  6. :KillProcessAndDeleteExe
  7. (TaskKill.exe /F /IM "%exeName%")1>NUL 2>&amp;1
  8. If NOT Exist "%exePath%" (GoTo :SelfDelete)
  9. (DEL /Q /F "%exePath%") || (GoTo :KillProcessAndDeleteExe)
  10.  
  11. :SelfDelete
  12. (DEL /Q /F "%~f0")
...Lo primero que hará el script será entrar en un búcle infinito donde se intentará matar el proceso, y una vez conseguido se dispondrá a eliminar el archivo, y por último eliminarse a sí mismo.



¿Cómo guardar y restaurar el estado expandido/colapsado de los nodos de un TreeView?

Pongámonos en situación, imaginemos que tenemos un control de tipo TreeView en el que tenemos que crear y destruir algunos de sus nodos o todos ellos de forma dinámica, y al hacerlo perderiamos el estado expandido/colapsado de cada nodo al refrescar la lista de nodos.

U otra situación distinta, en la que simplemente quisieramos guardar el estado del TreeView al cerrar la aplicación, para cargar ese estado en el próximo inicio de la aplicación.

Bien, pues para solucionar ese tipo de problema primero crearíamos la siguiente función que nos devolverá una lista con todos los nodos y sus nodos hijos de un TreeView:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets all the parent nodes and all its child nodes in the source <see cref="TreeView"/>.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim nodeList As List(Of TreeNode) = Me.TreeView1.GetAllNodesAndChildnodes()
  9. '''
  10. ''' For Each node As TreeNode In nodeList
  11. '''     ' ...
  12. ''' Next node
  13. ''' </code>
  14. ''' </example>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="sender">
  17. ''' The source <see cref="TreeView"/>.
  18. ''' </param>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. ''' <returns>
  21. ''' A <see cref="List(Of TreeNode)"/> containing all the parent nodes and all its child nodes.
  22. ''' </returns>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. Public Shared Function GetAllNodesAndChildnodes(ByVal sender As TreeView) As List(Of TreeNode)
  25.  
  26.    Dim nodes As New List(Of TreeNode)
  27.    Dim stack As New Stack(Of TreeNode)
  28.  
  29.    ' Bang all the top nodes into the queue.
  30.    For Each top As TreeNode In sender.Nodes
  31.        stack.Push(top)
  32.    Next
  33.  
  34.    While (stack.Count > 0)
  35.        Dim node As TreeNode = stack.Pop()
  36.        If (node IsNot Nothing) Then
  37.            ' Add the node to the list of nodes.
  38.            nodes.Add(node)
  39.  
  40.            If (node.Nodes IsNot Nothing) And (node.Nodes.Count > 0) Then
  41.                ' Enqueue the child nodes.
  42.                For Each child As TreeNode In node.Nodes
  43.                    stack.Push(child)
  44.                Next child
  45.            End If
  46.        End If
  47.    End While
  48.  
  49.    stack.Clear()
  50.    stack = Nothing
  51.    Return nodes
  52.  
  53. End Function

Ahora solo tenemos que crear una función para iterar los nodos obtenidos y así crear un "estado de guardado" (o save state), el cual consistitía en un diccionario que contendrá el código hash identificador de cada nodo, y un valor boolean indicando si el nodo está expandido o colapsado.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Saves the state of the source <see cref="TreeView"/> into a <see cref="Dictionary(Of Integer, Boolean)"/>
  4. ''' containing the hash code of each node and its expansion state.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <example> This is a code example.
  8. ''' <code>
  9. ''' Dim saveState As Dictionary(Of Integer, Boolean) = Me.TreeView1.SaveTreeState()
  10. ''' </code>
  11. ''' </example>
  12. ''' ----------------------------------------------------------------------------------------------------
  13. ''' <param name="sender">
  14. ''' The source <see cref="TreeView"/>.
  15. ''' </param>
  16. ''' ---------------------------------------------------------------------------------------------------
  17. ''' <returns>
  18. ''' A <see cref="Dictionary(Of Integer, Boolean)"/> containing the hash code of each node and its expansion state.
  19. ''' </returns>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. Public Shared Function SaveTreeState(ByVal sender As TreeView) As Dictionary(Of Integer, Boolean)
  22.  
  23.    Dim nodeList As List(Of TreeNode) = GetAllNodesAndChildnodes(sender)
  24.    Dim nodeStates As New Dictionary(Of Integer, Boolean)()
  25.  
  26.    For Each node As TreeNode In nodeList
  27.        nodeStates.Add(node.GetHashCode(), node.IsExpanded)
  28.    Next
  29.  
  30.    Return nodeStates
  31.  
  32. End Function

Y por último la función para restaurar un estado de guardado:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Restores a state of the source <see cref="TreeView"/> previously saved using the <see cref="SaveTreeState"/> function.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim saveState As Dictionary(Of Integer, Boolean)
  9. '''
  10. ''' Private Sub Button_SaveTreeState(sender As Object, e As EventArgs) Handles Button_SaveTreeState.Click
  11. '''     saveState = Me.TreeView1.SaveTreeState()
  12. ''' End Sub
  13. '''
  14. ''' Private Sub Button_RestoreTreeState(sender As Object, e As EventArgs) Handles Button_RestoreTreeState.Click
  15. '''     Me.TreeView1.RestoreTreeState(saveState)
  16. ''' End Sub
  17. ''' </code>
  18. ''' </example>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. ''' <param name="sender">
  21. ''' The source <see cref="TreeView"/>.
  22. ''' </param>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. ''' <param name="saveState">
  25. ''' A <see cref="Dictionary(Of Integer, Boolean)"/> containing the hash code of each node and its expansion state.
  26. ''' </param>
  27. ''' ----------------------------------------------------------------------------------------------------
  28. Public Shared Sub RestoreTreeState(ByVal sender As TreeView, ByVal saveState As Dictionary(Of Integer, Boolean))
  29.  
  30.    Dim nodeList As List(Of TreeNode) = GetAllNodesAndChildnodes(sender)
  31.  
  32.    For Each node As TreeNode In nodeList
  33.  
  34.        Dim hash As Integer = node.GetHashCode()
  35.  
  36.        If saveState.ContainsKey(hash) Then
  37.  
  38.            If saveState(hash) Then
  39.                node.Expand()
  40.            Else
  41.                node.Collapse()
  42.            End If
  43.  
  44.        End If
  45.  
  46.    Next
  47.  
  48. End Sub



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework de pago ElektroKit.


« Última modificación: 1 Abril 2017, 18:06 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #502 en: 1 Abril 2017, 17:55 pm »

¿Cómo determinar cual es la versión más reciente instalada de .NET Framework en la máquina actual?.

Aquí les dejo el código fuente completo:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Determines which is the most recent version of the .NET Framework runtimes installed on the current machine.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim frameworkVersion As Version = GetMostRecentInstalledFrameworkVersion()
  9. ''' Console.WriteLine(frameworkVersion.ToString())
  10. ''' </code>
  11. ''' </example>
  12. ''' ----------------------------------------------------------------------------------------------------
  13. ''' <remarks>
  14. ''' Credits to Microsoft: <see href="http://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx"/>
  15. ''' </remarks>
  16. ''' ----------------------------------------------------------------------------------------------------
  17. ''' <returns>
  18. ''' The resulting .NET Framework <see cref="Version"/>.
  19. ''' </returns>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. <DebuggerStepperBoundary>
  22. Private Shared Function GetMostRecentInstalledFrameworkVersion() As Version
  23.  
  24.    ' .NET 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1
  25.    Using ndpKey As RegistryKey =
  26.        RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).
  27.                    OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\", writable:=False)
  28.  
  29.        If (ndpKey IsNot Nothing) AndAlso (ndpKey.GetValue("Release") IsNot Nothing) Then
  30.            Dim releaseVersion As Integer = CInt(ndpKey.GetValue("Release"))
  31.            Select Case releaseVersion
  32.                Case >= 394254
  33.                    Return New Version(4, 6, 1)
  34.                Case >= 393295
  35.                    Return New Version(4, 6)
  36.                Case >= 379893
  37.                    Return New Version(4, 5, 2)
  38.                Case >= 378675
  39.                    Return New Version(4, 5, 1)
  40.                Case >= 378389
  41.                    Return New Version(4, 5)
  42.            End Select
  43.        End If
  44.    End Using
  45.  
  46.    ' .NET 1.0, 2.0, 3.0, 3.5, 4.0
  47.    Using ndpKey As RegistryKey =
  48.        RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
  49.                    OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\", writable:=False)
  50.  
  51.        For Each versionKeyName As String In ndpKey.GetSubKeyNames().OrderByDescending(Function(x As String) x)
  52.            If versionKeyName.ToLower().StartsWith("v") Then
  53.                Return New Version(versionKeyName.ToLower().TrimStart("v"c))
  54.            End If
  55.        Next versionKeyName
  56.    End Using
  57.  
  58.    Return New Version()
  59.  
  60. End Function

Personálmente recomiendo decorar esta funcionalidad mediante una propiedad de sólo lectura, tal que así:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets a value that determines which is the most recent version of the .NET Framework runtimes installed
  4. ''' on the current machine.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <value>
  8. ''' A value that determines which is the most recent version of the .NET Framework runtimes installed
  9. ''' on the current machine.
  10. ''' </value>
  11. ''' ----------------------------------------------------------------------------------------------------
  12. Public Shared ReadOnly Property MostRecentInstalledFrameworkVersion As Version
  13.    <DebuggerStepThrough>
  14.    Get
  15.        Return GetMostRecentInstalledFrameworkVersion()
  16.    End Get
  17. End Property

Modo de empleo:
Código
  1. Dim frameworkVersion As Version = GetMostRecentInstalledFrameworkVersion()
  2. Console.WriteLine(frameworkVersion.ToString())

Notas: Faltaría implementar la versión de .NET 4.6.2. Aparte de eso no he podio testear en profundidad el resultado obtenido en un equipo que tenga instalado .NET 1.0, 2.0, 3.0, 3.5 o 4.0, si encuentran algún error diganmelo.



Códigos de error Win32.

Esto que voy a compartir a continuación es una enumeración con todos los errores Win32 de la API de Windows, en total son +13.000 lineas de código, así que os dejo un enlace externo:


El propósito de gigantesca enumeración es proveer una manera sencilla, directa y eficiente de determinar que error nos devuelve en ocasiones una función de la API de Windows y cual es el significado de dicho código de error.

No confundir un código de error Win32 con un código de error H_RESULT, esto último define muchos errores Win32 pero con otros valores.

Recordad que la librería de clases de .NET Framework expone algunos miembros muy útiles para la evaluación de errores de funciones no administradas, Marshal.GetLastWin32Error(), Marshal.GetHRForLastWin32Error() y Marshal.ThrowExceptionForHR() así como el tipo excepción System.ComponentModel.Win32Exception que podemos invocar para informarle de un error Win32 específico al usuario.



¿Cómo prevenir el Flickering de un control Win32?.

Uno de los mayores problemas estéticos y también de lo más común al trabajar con los controles de la tecnología WindowsForms es el Flickering. El Flicker consiste en un desagradable parpadeo de la imagen en donde la imagen desaparece por un breve tiempo lapso de tiempo hasta que vuelve a aparecer, como un parpadeo. Es un problema visual que afecta a la estética del control, y suele producirse muy a menudo cuando el control necesita realizar operaciones de dibujo muy expensivas, o cuando estamos trabajando con transparencias.

Una descripción más detallada del flickering: https://en.wikipedia.org/wiki/Flicker_(screen)

¿Cómo se soluciona el Flickering?, pues lamentablemente no se puede solucionar completamente, pero si que podemos llegar a reducir el Flickering considerablemente y en el mejor de los casos hasta llegar a dejar de percibirlo del todo y poder decir que ya no hay Flickering en el control, ¿pero cómo se hace?, pues una solución cotidiana sería con un bufer doble de memoria, o double buffering.

Cuando el double buffering está activado, todas las operaciones de dibujado del control son renderizadas primero a un bufer de memoria en vez de ser renderizadas directamente a la superficie de dibujado en la pantalla. Cuando todas las operaciones de dibujado han sido completadas, el bufer de memoria es copiado directamente a la superficie de dibujado asociada a él.

Para tratar de solventar los problemas de Flickering cuando estamos desarrollando un control de usuario, he desarrollado una interfáz con nombre IBufferedControl, la cual implementariamos en nuestro control:

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 20-March-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Properties "
  9.  
  10. ' CreateParams As CreateParams
  11. ' DoubleBuffered As Boolean
  12. ' PreventFlickering As Boolean
  13.  
  14. #End Region
  15.  
  16. #End Region
  17.  
  18. #Region " Option Statements "
  19.  
  20. Option Strict On
  21. Option Explicit On
  22. Option Infer Off
  23.  
  24. #End Region
  25.  
  26. #Region " Imports "
  27.  
  28. Imports System.ComponentModel
  29. Imports System.Windows.Forms
  30.  
  31. #End Region
  32.  
  33. #Region " IBufferedControl "
  34.  
  35. Namespace Types
  36.  
  37.    ''' ----------------------------------------------------------------------------------------------------
  38.    ''' <summary>
  39.    ''' Provides simple double buffering (anti flickering) functionality for a Windows Forms <see cref="Control"/>,
  40.    ''' such for example a <see cref="TextBox"/>.
  41.    ''' </summary>
  42.    ''' ----------------------------------------------------------------------------------------------------
  43.    Public Interface IBufferedControl
  44.  
  45.        ''' ----------------------------------------------------------------------------------------------------
  46.        ''' <summary>
  47.        ''' Gets the required creation parameters when the control handle is created.
  48.        ''' </summary>
  49.        ''' ----------------------------------------------------------------------------------------------------
  50.        ''' <value>
  51.        ''' The creation parameters.
  52.        ''' </value>
  53.        ''' ----------------------------------------------------------------------------------------------------
  54.        <Browsable(False)>
  55.        <EditorBrowsable(EditorBrowsableState.Advanced)>
  56.        ReadOnly Property CreateParams As CreateParams
  57.        ' Implementation Exmple:
  58.        '
  59.        ' Protected Overrides ReadOnly Property CreateParams As CreateParams Implements IBufferedControl.CreateParams
  60.        '     Get
  61.        '         If (Me.preventFlickeringB) Then
  62.        '             Dim cp As CreateParams = MyBase.CreateParams
  63.        '             cp.ExStyle = (cp.ExStyle Or CInt(WindowStylesEx.Composited))
  64.        '             Return cp
  65.        '         Else
  66.        '             Return MyBase.CreateParams
  67.        '         End If
  68.        '     End Get
  69.        ' End Property
  70.  
  71.        ''' ----------------------------------------------------------------------------------------------------
  72.        ''' <summary>
  73.        ''' Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer
  74.        ''' to reduce or prevent flicker.
  75.        ''' </summary>
  76.        ''' ----------------------------------------------------------------------------------------------------
  77.        ''' <value>
  78.        ''' <see langword="True"/> if the surface of the control should be drawn using double buffering;
  79.        ''' otherwise, <see langword="False"/>.
  80.        ''' </value>
  81.        ''' ----------------------------------------------------------------------------------------------------
  82.        <Browsable(True)>
  83.        <EditorBrowsable(EditorBrowsableState.Always)>
  84.        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  85.        <Localizable(True)>
  86.        <Category("Behavior")>
  87.        <Description("Indicates whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker.")>
  88.        <DefaultValue(GetType(Boolean), "True")>
  89.        Property DoubleBuffered As Boolean
  90.        ' Implementation Exmple:
  91.        '
  92.        ' Public Overridable Shadows Property DoubleBuffered As Boolean Implements IBufferedControl.DoubleBuffered
  93.        '     Get
  94.        '         Return MyBase.DoubleBuffered
  95.        '     End Get
  96.        '     Set(ByVal value As Boolean)
  97.        '         Me.SetStyle(ControlStyles.DoubleBuffer, value)
  98.        '         MyBase.DoubleBuffered = value
  99.        '     End Set
  100.        ' End Property
  101.  
  102.        ''' ----------------------------------------------------------------------------------------------------
  103.        ''' <summary>
  104.        ''' Gets or sets a value that indicates whether the control should avoid unwanted flickering effects.
  105.        ''' <para></para>
  106.        ''' If <see langword="True"/>, this will avoid any flickering effect on the control, however,
  107.        ''' it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.
  108.        ''' <para></para>
  109.        ''' This negative impact doesn't affect to the performance of the application itself,
  110.        ''' just to the performance of this control.
  111.        ''' </summary>
  112.        ''' ----------------------------------------------------------------------------------------------------
  113.        ''' <value>
  114.        ''' A value that indicates whether the control should avoid unwanted flickering effects.
  115.        ''' </value>
  116.        ''' ----------------------------------------------------------------------------------------------------
  117.        <Browsable(True)>
  118.        <EditorBrowsable(EditorBrowsableState.Always)>
  119.        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  120.        <Localizable(True)>
  121.        <Category("Behavior")>
  122.        <Description("Indicates whether the control should avoid unwanted flickering effects. If True, this will avoid any flickering effect on the control, however, it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.")>
  123.        <DefaultValue(GetType(Boolean), "False")>
  124.        Property PreventFlickering As Boolean
  125.        ' Implementation Exmple:
  126.        '
  127.        ' Public Overridable Property PreventFlickering As Boolean Implements IBufferedControl.PreventFlickering
  128.        '     Get
  129.        '         Return Me.preventFlickeringB
  130.        '     End Get
  131.        '     Set(ByVal value As Boolean)
  132.        '         Me.preventFlickeringB = value
  133.        '     End Set
  134.        ' End Property
  135.        ' ''' ----------------------------------------------------------------------------------------------------
  136.        ' ''' <summary>
  137.        ' ''' ( Backing Field )
  138.        ' ''' A value that indicates whether the control should avoid unwanted flickering effects.
  139.        ' ''' </summary>
  140.        ' ''' ----------------------------------------------------------------------------------------------------
  141.        ' Private preventFlickeringB As Boolean
  142.  
  143.    End Interface
  144.  
  145. End Namespace
  146.  
  147. #End Region

Un ejemplo de implementación:
Código
  1. <DisplayName("MyControl")>
  2. <Description("A extended control.")>
  3. <DesignTimeVisible(True)>
  4. <DesignerCategory("UserControl")>
  5. <ToolboxBitmap(GetType(UserControl))>
  6. <ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Require)>
  7. <PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
  8. Public Class MyControl : Inherits UserControl : Implements IBufferedControl
  9.  
  10.    ''' ----------------------------------------------------------------------------------------------------
  11.    ''' <summary>
  12.    ''' Gets the required creation parameters when the control handle is created.
  13.    ''' <para></para>
  14.    ''' The information returned by the <see cref="CreateParams"/> property is used to pass information about the
  15.    ''' initial state and appearance of this control, at the time an instance of this class is being created.
  16.    ''' </summary>
  17.    ''' ----------------------------------------------------------------------------------------------------
  18.    ''' <value>
  19.    ''' The creation parameters.
  20.    ''' </value>
  21.    ''' ----------------------------------------------------------------------------------------------------
  22.    <Browsable(False)>
  23.    <EditorBrowsable(EditorBrowsableState.Advanced)>
  24.    <Description("The required creation parameters when the control handle is created.")>
  25.    Protected Overrides ReadOnly Property CreateParams As CreateParams Implements IBufferedControl.CreateParams
  26.        Get
  27.            If (Me.preventFlickeringB) Then
  28.                Dim cp As CreateParams = MyBase.CreateParams
  29.                cp.ExStyle = (cp.ExStyle Or CInt(WindowStylesEx.Composited))
  30.                Return cp
  31.            Else
  32.                Return MyBase.CreateParams
  33.            End If
  34.        End Get
  35.    End Property
  36.  
  37.    ''' ----------------------------------------------------------------------------------------------------
  38.    ''' <summary>
  39.    ''' Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer
  40.    ''' to reduce or prevent flicker.
  41.    ''' </summary>
  42.    ''' ----------------------------------------------------------------------------------------------------
  43.    ''' <value>
  44.    ''' <see langword="True"/> if the surface of the control should be drawn using double buffering;
  45.    ''' otherwise, <see langword="False"/>.
  46.    ''' </value>
  47.    ''' ----------------------------------------------------------------------------------------------------
  48.    <Browsable(True)>
  49.    <EditorBrowsable(EditorBrowsableState.Always)>
  50.    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  51.    <Localizable(True)>
  52.    <Category("Behavior")>
  53.    <Description("Indicates whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker.")>
  54.    <DefaultValue(GetType(Boolean), "False")>
  55.    Public Overridable Shadows Property DoubleBuffered As Boolean Implements IBufferedControl.DoubleBuffered
  56.        Get
  57.            Return MyBase.DoubleBuffered
  58.        End Get
  59.        Set(ByVal value As Boolean)
  60.            Me.SetStyle(ControlStyles.DoubleBuffer, value)
  61.            MyBase.DoubleBuffered = value
  62.        End Set
  63.    End Property
  64.  
  65.    ''' ----------------------------------------------------------------------------------------------------
  66.    ''' <summary>
  67.    ''' Gets or sets a value that indicates whether the control should avoid unwanted flickering effects.
  68.    ''' <para></para>
  69.    ''' If <see langword="True"/>, this will avoid any flickering effect on the control, however,
  70.    ''' it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.
  71.    ''' <para></para>
  72.    ''' This negative impact doesn't affect to the performance of the application itself,
  73.    ''' just to the performance of this control.
  74.    ''' </summary>
  75.    ''' ----------------------------------------------------------------------------------------------------
  76.    ''' <value>
  77.    ''' A value that indicates whether the control should avoid unwanted flickering effects.
  78.    ''' </value>
  79.    ''' ----------------------------------------------------------------------------------------------------
  80.    <Browsable(True)>
  81.    <EditorBrowsable(EditorBrowsableState.Always)>
  82.    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  83.    <Localizable(False)>
  84.    <Category("Behavior")>
  85.    <Description("Indicates whether the control should avoid unwanted flickering effects. If True, this will avoid any flickering effect on the control, however, it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.")>
  86.    <DefaultValue(GetType(Boolean), "False")>
  87.    Public Overridable Property PreventFlickering As Boolean Implements IBufferedControl.PreventFlickering
  88.        Get
  89.            Return Me.preventFlickeringB
  90.        End Get
  91.        Set(ByVal value As Boolean)
  92.            Me.preventFlickeringB = value
  93.        End Set
  94.    End Property
  95.    ''' ----------------------------------------------------------------------------------------------------
  96.    ''' <summary>
  97.    ''' ( Backing Field )
  98.    ''' A value that indicates whether the control should avoid unwanted flickering effects.
  99.    ''' </summary>
  100.    ''' ----------------------------------------------------------------------------------------------------
  101.    Private preventFlickeringB As Boolean
  102.  
  103.    Public Sub New()
  104.        MyBase.SuspendLayout()
  105.        ' MyBase.DoubleBuffered = True
  106.        ' Me.preventFlickeringB = True
  107.        MyBase.ResumeLayout(performLayout:=False)
  108.    End Sub
  109.  
  110. End Class



¿Cómo calcular la distancia (de 2 dimensiones) entre dos puntos?.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Calculates the distance between two points in two dimensions in the coordinate system.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <remarks>
  7. ''' Pythagorean theorem: <see href="http://en.wikipedia.org/wiki/Pythagorean_theorem"/>
  8. ''' </remarks>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <example> This is a code example.
  11. ''' <code>
  12. ''' Dim distance As Double = CalculateDistance2D(New PointF(1, 1), New PointF(2, 2))
  13. ''' </code>
  14. ''' </example>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="pointA">
  17. ''' The first point.
  18. ''' </param>
  19. '''
  20. ''' <param name="pointB">
  21. ''' The second point.
  22. ''' </param>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. ''' <returns>
  25. ''' The resulting distance.
  26. ''' </returns>
  27. ''' ----------------------------------------------------------------------------------------------------
  28. Public Shared Function CalculateDistance2D(ByVal pointA As PointF, ByVal pointB As PointF) As Double
  29.  
  30.    ' Pythagoras theorem: c^2 = a^2 + b^2
  31.    ' thus c = square root(a^2 + b^2)
  32.    Dim a As Double = (pointB.X - pointA.X)
  33.    Dim b As Double = (pointB.Y - pointA.Y)
  34.  
  35.    Return Math.Sqrt(a * a + b * b)
  36.  
  37. End Function



¿Cómo subscribirnos a eventos del sistema?.

Microsoft Windows expone una infraestructura llamada WMI (Windows Management Instrumentation) mediante la que provee una serie de classes que podemos utilizar para subscribbirnos a eventos del sistema o dicho coloquiálmente "monitorizar eventos", como por ejemplo cambios de hardware, cambios de aplicaciones instaladas o desinstaladas, cambios en el nivel de batería de un portatil, cambios en el registro de Windows, y un largo etcétera.

La lista de classes podemos encontrarla en MSDN: https://msdn.microsoft.com/en-us/library/aa394554(v=vs.85).aspx

Hay varios tipos de classes, un tipo de classes serían representativas, es decir para representar información de consultas realizadas a WMI, y otro tipo serían las classes de eventos. Una class de evento la utilizariamos para subscribirnos al tipo de evento que provee.

Para subscribirnos a una clase de evento, la librería de clases de .NET Framework espone la clase ManagementEventWatcher. Yo he desarrollado la siguiente class que hereda de la class ManagementEventWatcher, con la intención de añadir algunos constructores específicos para facilitar todavía más su uso y abstraer en mayor medida el nivel de complejidad.

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 21-March-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Constructors "
  9.  
  10. ' New(String)
  11. ' New(String, Single)
  12. ' New(String, Timespan)
  13. ' New(String, String, Single)
  14. ' New(String, String, Timespan)
  15. ' New(String, String, String(), UInteger)
  16. ' New(String, String, String(), Timespan)
  17.  
  18. ' New(SelectQuery)
  19. ' New(SelectQuery, Single)
  20. ' New(SelectQuery, Timespan)
  21. ' New(SelectQuery, UInteger)
  22.  
  23. #End Region
  24.  
  25. #Region " Events "
  26.  
  27. ' EventArrived As EventArrivedEventHandler
  28.  
  29. #End Region
  30.  
  31. #Region " Methods "
  32.  
  33. ' Start()
  34. ' Stop()
  35. ' Dispose()
  36.  
  37. #End Region
  38.  
  39. #End Region
  40.  
  41. #Region " Option Statements "
  42.  
  43. Option Strict On
  44. Option Explicit On
  45. Option Infer Off
  46.  
  47. #End Region
  48.  
  49. #Region " Imports "
  50.  
  51. Imports System.ComponentModel
  52. Imports System.Management
  53.  
  54. #End Region
  55.  
  56. #Region " WMI Event Watcher "
  57.  
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    ''' <summary>
  60.    ''' A WMI event monitor that notifies about event arrivals for the subscribed event class.
  61.    ''' </summary>
  62.    ''' ----------------------------------------------------------------------------------------------------
  63.    <DesignerCategory("code")>
  64.    <ImmutableObject(False)>
  65.    Public Class WMIEventWatcher : Inherits ManagementEventWatcher
  66.  
  67. #Region " Constructors "
  68.  
  69.        ''' ----------------------------------------------------------------------------------------------------
  70.        ''' <summary>
  71.        ''' Prevents a default instance of the <see cref="WMIEventWatcher"/> class from being created.
  72.        ''' </summary>
  73.        ''' ----------------------------------------------------------------------------------------------------
  74.        <DebuggerNonUserCode>
  75.        Private Sub New()
  76.        End Sub
  77.  
  78.        ''' ----------------------------------------------------------------------------------------------------
  79.        ''' <summary>
  80.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  81.        ''' </summary>
  82.        ''' ----------------------------------------------------------------------------------------------------
  83.        ''' <param name="eventClassName">
  84.        ''' The name of the WMI event class to subscribe for.
  85.        ''' </param>
  86.        ''' ----------------------------------------------------------------------------------------------------
  87.        <DebuggerStepThrough>
  88.        Public Sub New(ByVal eventClassName As String)
  89.  
  90.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=1.0F)
  91.  
  92.        End Sub
  93.  
  94.        ''' ----------------------------------------------------------------------------------------------------
  95.        ''' <summary>
  96.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  97.        ''' </summary>
  98.        ''' ----------------------------------------------------------------------------------------------------
  99.        ''' <param name="eventClassName">
  100.        ''' The name of the WMI event class to subscribe for.
  101.        ''' </param>
  102.        '''
  103.        ''' <param name="withinInterval">
  104.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  105.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  106.        ''' </param>
  107.        ''' ----------------------------------------------------------------------------------------------------
  108.        <DebuggerStepThrough>
  109.        Public Sub New(ByVal eventClassName As String,
  110.                       ByVal withinInterval As Single)
  111.  
  112.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=withinInterval)
  113.  
  114.        End Sub
  115.  
  116.        ''' ----------------------------------------------------------------------------------------------------
  117.        ''' <summary>
  118.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  119.        ''' </summary>
  120.        ''' ----------------------------------------------------------------------------------------------------
  121.        ''' <param name="eventClassName">
  122.        ''' The name of the WMI event class to subscribe for.
  123.        ''' </param>
  124.        '''
  125.        ''' <param name="withinInterval">
  126.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  127.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  128.        ''' </param>
  129.        ''' ----------------------------------------------------------------------------------------------------
  130.        <DebuggerStepThrough>
  131.        Public Sub New(ByVal eventClassName As String,
  132.                       ByVal withinInterval As TimeSpan)
  133.  
  134.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=withinInterval)
  135.  
  136.        End Sub
  137.  
  138.        ''' ----------------------------------------------------------------------------------------------------
  139.        ''' <summary>
  140.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  141.        ''' </summary>
  142.        ''' ----------------------------------------------------------------------------------------------------
  143.        ''' <param name="eventClassName">
  144.        ''' The name of the WMI event class to subscribe for.
  145.        ''' </param>
  146.        '''
  147.        ''' <param name="condition">
  148.        ''' The condition to be applied to events of the specified class in the
  149.        ''' <paramref name="eventClassName"/> parameter.
  150.        ''' </param>
  151.        '''
  152.        ''' <param name="withinInterval">
  153.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  154.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  155.        ''' </param>
  156.        ''' ----------------------------------------------------------------------------------------------------
  157.        <DebuggerStepThrough>
  158.        Public Sub New(ByVal eventClassName As String,
  159.                       ByVal condition As String,
  160.                       ByVal withinInterval As Single)
  161.  
  162.            Me.New(eventClassName, condition, TimeSpan.FromSeconds(withinInterval))
  163.  
  164.        End Sub
  165.  
  166.        ''' ----------------------------------------------------------------------------------------------------
  167.        ''' <summary>
  168.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  169.        ''' </summary>
  170.        ''' ----------------------------------------------------------------------------------------------------
  171.        ''' <param name="eventClassName">
  172.        ''' The name of the WMI event class to subscribe for.
  173.        ''' </param>
  174.        '''
  175.        ''' <param name="condition">
  176.        ''' The condition to be applied to events of the specified class in the
  177.        ''' <paramref name="eventClassName"/> parameter.
  178.        ''' </param>
  179.        '''
  180.        ''' <param name="withinInterval">
  181.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  182.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  183.        ''' </param>
  184.        ''' ----------------------------------------------------------------------------------------------------
  185.        <DebuggerStepThrough>
  186.        Public Sub New(ByVal eventClassName As String,
  187.                       ByVal condition As String,
  188.                       ByVal withinInterval As TimeSpan)
  189.  
  190.            MyBase.Query = New WqlEventQuery(eventClassName:=eventClassName,
  191.                                             condition:=condition,
  192.                                             withinInterval:=withinInterval)
  193.  
  194.        End Sub
  195.  
  196.        ''' ----------------------------------------------------------------------------------------------------
  197.        ''' <summary>
  198.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  199.        ''' </summary>
  200.        ''' ----------------------------------------------------------------------------------------------------
  201.        ''' <param name="eventClassName">
  202.        ''' The name of the WMI event class to subscribe for.
  203.        ''' </param>
  204.        '''
  205.        ''' <param name="condition">
  206.        ''' The condition to be applied to events of the specified class in the
  207.        ''' <paramref name="eventClassName"/> parameter.
  208.        ''' </param>
  209.        '''
  210.        ''' <param name="groupByPropertyList">
  211.        ''' The properties in the event class by which the events should be grouped.
  212.        ''' </param>
  213.        '''
  214.        ''' <param name="groupWithinInterval">
  215.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  216.        ''' rather than many events.
  217.        ''' </param>
  218.        ''' ----------------------------------------------------------------------------------------------------
  219.        <DebuggerStepThrough>
  220.        Public Sub New(ByVal eventClassName As String,
  221.                       ByVal condition As String,
  222.                       ByVal groupByPropertyList As String(),
  223.                       ByVal groupWithinInterval As UInteger)
  224.  
  225.            Me.New(eventClassName, condition, groupByPropertyList, TimeSpan.FromSeconds(groupWithinInterval))
  226.  
  227.        End Sub
  228.  
  229.        ''' ----------------------------------------------------------------------------------------------------
  230.        ''' <summary>
  231.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  232.        ''' </summary>
  233.        ''' ----------------------------------------------------------------------------------------------------
  234.        ''' <param name="eventClassName">
  235.        ''' The name of the WMI event class to subscribe for.
  236.        ''' </param>
  237.        '''
  238.        ''' <param name="condition">
  239.        ''' The condition to be applied to events of the specified class in the
  240.        ''' <paramref name="eventClassName"/> parameter.
  241.        ''' </param>
  242.        '''
  243.        ''' <param name="groupByPropertyList">
  244.        ''' The properties in the event class by which the events should be grouped.
  245.        ''' </param>
  246.        '''
  247.        ''' <param name="groupWithinInterval">
  248.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  249.        ''' rather than many events.
  250.        ''' </param>
  251.        ''' ----------------------------------------------------------------------------------------------------
  252.        <DebuggerStepThrough>
  253.        Public Sub New(ByVal eventClassName As String,
  254.                       ByVal condition As String,
  255.                       ByVal groupByPropertyList As String(),
  256.                       ByVal groupWithinInterval As TimeSpan)
  257.  
  258.            MyBase.Query = New WqlEventQuery(eventClassName:=eventClassName,
  259.                                             condition:=condition,
  260.                                             groupWithinInterval:=groupWithinInterval,
  261.                                             groupByPropertyList:=groupByPropertyList)
  262.  
  263.        End Sub
  264.  
  265.        ''' ----------------------------------------------------------------------------------------------------
  266.        ''' <summary>
  267.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  268.        ''' </summary>
  269.        ''' ----------------------------------------------------------------------------------------------------
  270.        ''' <param name="query">
  271.        ''' The WMI select query of the event class to subscribe for.
  272.        ''' </param>
  273.        ''' ----------------------------------------------------------------------------------------------------
  274.        <DebuggerStepThrough>
  275.        Public Sub New(ByVal query As SelectQuery)
  276.  
  277.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=1.0F)
  278.  
  279.        End Sub
  280.  
  281.        ''' ----------------------------------------------------------------------------------------------------
  282.        ''' <summary>
  283.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  284.        ''' </summary>
  285.        ''' ----------------------------------------------------------------------------------------------------
  286.        ''' <param name="query">
  287.        ''' The WMI select query of the event class to subscribe for.
  288.        ''' </param>
  289.        '''
  290.        ''' <param name="withinInterval">
  291.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  292.        ''' specified class in the <paramref name="query"/> parameter.
  293.        ''' </param>
  294.        ''' ----------------------------------------------------------------------------------------------------
  295.        <DebuggerStepThrough>
  296.        Public Sub New(ByVal query As SelectQuery,
  297.                       ByVal withinInterval As Single)
  298.  
  299.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=TimeSpan.FromSeconds(withinInterval))
  300.  
  301.        End Sub
  302.  
  303.        ''' ----------------------------------------------------------------------------------------------------
  304.        ''' <summary>
  305.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  306.        ''' </summary>
  307.        ''' ----------------------------------------------------------------------------------------------------
  308.        ''' <param name="query">
  309.        ''' The WMI select query of the event class to subscribe for.
  310.        ''' </param>
  311.        '''
  312.        ''' <param name="withinInterval">
  313.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  314.        ''' specified class in the <paramref name="query"/> parameter.
  315.        ''' </param>
  316.        ''' ----------------------------------------------------------------------------------------------------
  317.        <DebuggerStepThrough>
  318.        Public Sub New(ByVal query As SelectQuery,
  319.                       ByVal withinInterval As TimeSpan)
  320.  
  321.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=withinInterval)
  322.  
  323.        End Sub
  324.  
  325.        ''' ----------------------------------------------------------------------------------------------------
  326.        ''' <summary>
  327.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  328.        ''' </summary>
  329.        ''' ----------------------------------------------------------------------------------------------------
  330.        ''' <param name="query">
  331.        ''' The WMI select query of the event class to subscribe for and its selected properties.
  332.        ''' </param>
  333.        '''
  334.        ''' <param name="groupWithinInterval">
  335.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  336.        ''' rather than many events.
  337.        ''' </param>
  338.        ''' ----------------------------------------------------------------------------------------------------
  339.        <DebuggerStepThrough>
  340.        Public Sub New(ByVal query As SelectQuery,
  341.                       ByVal groupWithinInterval As UInteger)
  342.  
  343.            Dim strArray As String() = New String(query.SelectedProperties.Count - 1) {}
  344.            query.SelectedProperties.CopyTo(strArray, 0)
  345.  
  346.            MyBase.Query = New WqlEventQuery(eventClassName:=query.ClassName,
  347.                                             condition:=query.Condition,
  348.                                             groupWithinInterval:=TimeSpan.FromSeconds(groupWithinInterval),
  349.                                             groupByPropertyList:=strArray)
  350.  
  351.        End Sub
  352.  
  353. #End Region
  354.  
  355.    End Class
  356.  
  357. #End Region

Ejemplo de uso para subscribirnos a la class Win32_VolumeChangeEvent, la cual nos informa de cambios de volumen, del montaje y desmontaje de particiones del sistema:

Código
  1. Public NotInheritable Class Form1 : Inherits Form
  2.  
  3.    Private WithEvents eventWatcher As New WMIEventWatcher("Win32_VolumeChangeEvent", withinInterval:=0.5F)
  4.  
  5.    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
  6.        Me.eventWatcher.Scope = New ManagementScope("root\CIMV2", New ConnectionOptions() With {.EnablePrivileges = True})
  7.        Me.eventWatcher.Start()
  8.    End Sub
  9.  
  10.    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
  11.        Me.eventWatcher.Dispose()
  12.    End Sub
  13.  
  14.    Private Sub EventWatcher_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs) _
  15.    Handles eventWatcher.EventArrived
  16.        Dim driveName As String = CStr(e.NewEvent.Properties("DriveName").Value)
  17.        Dim eventType As Integer = CInt(e.NewEvent.Properties("EventType").Value)
  18.  
  19.        Console.WriteLine(String.Format("Drive Name: {0}", driveName))
  20.        Console.WriteLine(String.Format("Event Type: {0}", eventType))
  21.    End Sub
  22.  
  23. End Class

Ejemplo de uso para subscribirnos a la class Win32_LogicalDisk, mediante la cual con el uso de una condición en la consulta de WMI, nos reportará cambios de inserción y eyección en dispositivos de CD-ROM:

Código
  1. Public Class Form1 : Inherits Form
  2.  
  3.    Private WithEvents eventWatcher As New WMIEventWatcher(
  4.        "__InstanceModificationEvent",
  5.        condition:="TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5",
  6.        withinInterval:=0.5F
  7.    )
  8.  
  9.    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
  10.        Me.eventWatcher.Scope = New ManagementScope("root\CIMV2", New ConnectionOptions() With {.EnablePrivileges = True})
  11.        Me.eventWatcher.Start()
  12.    End Sub
  13.  
  14.    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
  15.        Me.eventWatcher.Dispose()
  16.    End Sub
  17.  
  18.    Private Sub EventWatcher_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs) Handles eventWatcher.EventArrived
  19.  
  20.        Using mo As ManagementBaseObject = DirectCast(pd.Value, ManagementBaseObject)
  21.  
  22.            Dim name As String = Convert.ToString(mo.Properties("Name").Value)
  23.            string label = Convert.ToString(mo.Properties("VolumeName").Value);
  24.  
  25.            Dim di As DriveInfo = (From item In DriveInfo.GetDrives()
  26.                                   Where String.IsNullOrEmpty(item.Name)
  27.                                  ).Single()
  28.  
  29.            If Not String.IsNullOrEmpty(di.VolumeLabel) Then
  30.  
  31.                Console.WriteLine(String.Format("CD has been inserted in drive {0}.", di.Name))
  32.            Else
  33.  
  34.                Console.WriteLine(String.Format("CD has been ejected from drive {0}.", di.Name))
  35.  
  36.            End If
  37.  
  38.        End Using
  39.  
  40.    End Sub
  41.  
  42. End Class
Nota: No he podido testear el ejemplo del dispositivo CD-ROM.



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework de pago ElektroKit.
« Última modificación: 1 Abril 2017, 18:07 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #503 en: 2 Abril 2017, 22:36 pm »

¿Cómo manipular imágenes GIF animadas?

La librería de clases de .NET Framework no expone ningún tipo para representar de forma específica una imagen GIF. Tenemos el tipo Bitmap, Icon, e Image para representar de forma global cualquier tipo de imagen (incluyendo un GIF). Pero... ¿y si queremos representar de forma específica una imagen GIF con todos sus frames?, pues esta clase que he desarrollado sería un buen comienzo para llevarlo a cabo:

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 02-April-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Constructors "
  9.  
  10. ' New(String)
  11. ' New(FileInfo)
  12. ' New(Image)
  13.  
  14. #End Region
  15.  
  16. #Region " Properties "
  17.  
  18. ' Image As Image
  19. ' FrameCount As Integer
  20. ' Frames(Integer) As Bitmap
  21. ' ActiveFrame As Bitmap
  22. ' ActiveFrameIndex As Integer
  23. ' EndOfFrames As Boolean
  24.  
  25. #End Region
  26.  
  27. #Region " Functions "
  28.  
  29. ' NextFrame() As Bitmap
  30. ' GetFrames() As List(Of Bitmap)
  31.  
  32. #End Region
  33.  
  34. #End Region
  35.  
  36. #Region " Option Statements "
  37.  
  38. Option Strict On
  39. Option Explicit On
  40. Option Infer Off
  41.  
  42. #End Region
  43.  
  44. #Region " Imports "
  45.  
  46. Imports System.Drawing
  47. Imports System.Drawing.Imaging
  48. Imports System.IO
  49.  
  50. #End Region
  51.  
  52. #Region " GIF "
  53.  
  54.    ''' ----------------------------------------------------------------------------------------------------
  55.    ''' <summary>
  56.    ''' Represents a GIF image.
  57.    ''' </summary>
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    Public Class GIF
  60.  
  61. #Region " Properties "
  62.  
  63.        ''' ----------------------------------------------------------------------------------------------------
  64.        ''' <summary>
  65.        ''' Gets the GIF image.
  66.        ''' </summary>
  67.        ''' ----------------------------------------------------------------------------------------------------
  68.        ''' <value>
  69.        ''' The GIF image.
  70.        ''' </value>
  71.        ''' ----------------------------------------------------------------------------------------------------
  72.        Public ReadOnly Property Image As Image
  73.  
  74.        ''' ----------------------------------------------------------------------------------------------------
  75.        ''' <summary>
  76.        ''' Gets the frame count of the GIF image.
  77.        ''' </summary>
  78.        ''' ----------------------------------------------------------------------------------------------------
  79.        ''' <value>
  80.        ''' The frame count of the GIF image.
  81.        ''' </value>
  82.        ''' ----------------------------------------------------------------------------------------------------
  83.        Public ReadOnly Property FrameCount As Integer
  84.  
  85.        ''' ----------------------------------------------------------------------------------------------------
  86.        ''' <summary>
  87.        ''' Gets the frame at the specified index.
  88.        ''' </summary>
  89.        ''' ----------------------------------------------------------------------------------------------------
  90.        ''' <value>
  91.        ''' The frame index.
  92.        ''' </value>
  93.        ''' ----------------------------------------------------------------------------------------------------
  94.        Default Public Overridable ReadOnly Property Frames(ByVal index As Integer) As Bitmap
  95.            <DebuggerStepperBoundary>
  96.            Get
  97.                Using img As Image = DirectCast(Me.Image.Clone(), Image)
  98.                    img.SelectActiveFrame(FrameDimension.Time, index)
  99.                    Return New Bitmap(img) ' Deep copy of the frame (only the frame).
  100.                End Using
  101.            End Get
  102.        End Property
  103.  
  104.        ''' ----------------------------------------------------------------------------------------------------
  105.        ''' <summary>
  106.        ''' Gets the active frame.
  107.        ''' </summary>
  108.        ''' ----------------------------------------------------------------------------------------------------
  109.        ''' <value>
  110.        ''' The active frame.
  111.        ''' </value>
  112.        ''' ----------------------------------------------------------------------------------------------------
  113.        Public Overridable ReadOnly Property ActiveFrame As Bitmap
  114.            <DebuggerStepperBoundary>
  115.            Get
  116.                Return New Bitmap(Me.Image) ' Deep copy of the frame (only the frame).
  117.            End Get
  118.        End Property
  119.  
  120.        ''' ----------------------------------------------------------------------------------------------------
  121.        ''' <summary>
  122.        ''' Gets the index in the frame count of the current active frame.
  123.        ''' </summary>
  124.        ''' ----------------------------------------------------------------------------------------------------
  125.        ''' <value>
  126.        ''' The index in the frame count of the current active frame.
  127.        ''' </value>
  128.        ''' ----------------------------------------------------------------------------------------------------
  129.        Public Property ActiveFrameIndex As Integer
  130.            <DebuggerStepThrough>
  131.            Get
  132.                Return Me.activeFrameIndexB
  133.            End Get
  134.            <DebuggerStepperBoundary>
  135.            Set(ByVal value As Integer)
  136.                If (value <> Me.activeFrameIndexB) Then
  137.                    Me.Image.SelectActiveFrame(FrameDimension.Time, value)
  138.                    Me.activeFrameIndexB = value
  139.                    Me.eof = (value = Me.FrameCount)
  140.                End If
  141.            End Set
  142.        End Property
  143.        ''' ----------------------------------------------------------------------------------------------------
  144.        ''' <summary>
  145.        ''' ( Backing Field )
  146.        ''' The index in the frame count of the current active frame.
  147.        ''' </summary>
  148.        ''' ----------------------------------------------------------------------------------------------------
  149.        Private activeFrameIndexB As Integer
  150.  
  151.        ''' ----------------------------------------------------------------------------------------------------
  152.        ''' <summary>
  153.        ''' Gets a value indicating whether the frame count is at EOF,
  154.        ''' this means there is no more frames to advance in the GIF image.
  155.        ''' </summary>
  156.        ''' ----------------------------------------------------------------------------------------------------
  157.        ''' <value>
  158.        ''' <see langword="True"/> if there is no more frames to advance in the GIF image; otherwise, <see langword="False"/>.
  159.        ''' </value>
  160.        ''' ----------------------------------------------------------------------------------------------------
  161.        Public ReadOnly Property EndOfFrames As Boolean
  162.            <DebuggerStepThrough>
  163.            Get
  164.                Return Me.eof
  165.            End Get
  166.        End Property
  167.        ''' ----------------------------------------------------------------------------------------------------
  168.        ''' <summary>
  169.        ''' ( Backing Field )
  170.        ''' A value indicating whether the frame count is at EOF,
  171.        ''' this means there is no more frames to advance in the GIF image.
  172.        ''' </summary>
  173.        ''' ----------------------------------------------------------------------------------------------------
  174.        Private eof As Boolean
  175.  
  176. #End Region
  177.  
  178. #Region " Constructors "
  179.  
  180.        ''' ----------------------------------------------------------------------------------------------------
  181.        ''' <summary>
  182.        ''' Prevents a default instance of the <see cref="GIF"/> class from being created.
  183.        ''' </summary>
  184.        ''' ----------------------------------------------------------------------------------------------------
  185.        <DebuggerNonUserCode>
  186.        Private Sub New()
  187.        End Sub
  188.  
  189.        ''' ----------------------------------------------------------------------------------------------------
  190.        ''' <summary>
  191.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  192.        ''' </summary>
  193.        ''' ----------------------------------------------------------------------------------------------------
  194.        ''' <param name="filepath">
  195.        ''' The filepath.
  196.        ''' </param>
  197.        ''' ----------------------------------------------------------------------------------------------------
  198.        <DebuggerStepThrough>
  199.        Public Sub New(ByVal filepath As String)
  200.  
  201.            Me.New(Image.FromFile(filepath))
  202.  
  203.        End Sub
  204.  
  205.        ''' ----------------------------------------------------------------------------------------------------
  206.        ''' <summary>
  207.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  208.        ''' </summary>
  209.        ''' ----------------------------------------------------------------------------------------------------
  210.        ''' <param name="file">
  211.        ''' The image file.
  212.        ''' </param>
  213.        ''' ----------------------------------------------------------------------------------------------------
  214.        <DebuggerStepThrough>
  215.        Public Sub New(ByVal file As FileInfo)
  216.  
  217.            Me.New(Image.FromFile(file.FullName))
  218.  
  219.        End Sub
  220.  
  221.        ''' ----------------------------------------------------------------------------------------------------
  222.        ''' <summary>
  223.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  224.        ''' </summary>
  225.        ''' ----------------------------------------------------------------------------------------------------
  226.        ''' <param name="img">
  227.        ''' The image.
  228.        ''' </param>
  229.        ''' ----------------------------------------------------------------------------------------------------
  230.        <DebuggerStepThrough>
  231.        Public Sub New(ByVal img As Image)
  232.  
  233.            Me.Image = img
  234.            Me.FrameCount = Me.Image.GetFrameCount(FrameDimension.Time)
  235.  
  236.        End Sub
  237.  
  238. #End Region
  239.  
  240. #Region " Public Methods "
  241.  
  242.        ''' ----------------------------------------------------------------------------------------------------
  243.        ''' <summary>
  244.        ''' Advances one position in the frame count and returns the next frame.
  245.        ''' </summary>
  246.        ''' ----------------------------------------------------------------------------------------------------
  247.        ''' <returns>
  248.        ''' The next frame.
  249.        ''' </returns>
  250.        ''' ----------------------------------------------------------------------------------------------------
  251.        <DebuggerStepThrough>
  252.        Public Overridable Function NextFrame() As Bitmap
  253.  
  254.            If (Me.eof) Then
  255.                Throw New IndexOutOfRangeException()
  256.  
  257.            Else
  258.                Dim frame As Bitmap = Me.Frames(Me.activeFrameIndexB)
  259.                Me.activeFrameIndexB += 1
  260.                Me.eof = (Me.activeFrameIndexB >= Me.FrameCount)
  261.                Return frame
  262.  
  263.            End If
  264.  
  265.        End Function
  266.  
  267.        ''' ----------------------------------------------------------------------------------------------------
  268.        ''' <summary>
  269.        ''' Gets a <see cref="List(Of Bitmap)"/> containing all the frames in the image.
  270.        ''' </summary>
  271.        ''' ----------------------------------------------------------------------------------------------------
  272.        ''' <returns>
  273.        ''' A <see cref="List(Of Bitmap)"/> containing all the frames in the image.
  274.        ''' </returns>
  275.        ''' ----------------------------------------------------------------------------------------------------
  276.        <DebuggerStepThrough>
  277.        Public Overridable Function GetFrames() As List(Of Bitmap)
  278.  
  279.            Using img As Image = DirectCast(Me.Image.Clone(), Image)
  280.                Return GetFramesFromImage(img)
  281.            End Using
  282.  
  283.        End Function
  284.  
  285. #End Region
  286.  
  287. #Region " Private Methods "
  288.  
  289.        ''' ----------------------------------------------------------------------------------------------------
  290.        ''' <summary>
  291.        ''' Gets a <see cref="List(Of Bitmap)"/> containing all the frames in the source GIF image.
  292.        ''' </summary>
  293.        ''' ----------------------------------------------------------------------------------------------------
  294.        ''' <param name="img">
  295.        ''' The source <see cref="Image"/>.
  296.        ''' </param>
  297.        ''' ----------------------------------------------------------------------------------------------------
  298.        ''' <returns>
  299.        ''' The resulting percentage difference value between the two specified images.
  300.        ''' </returns>
  301.        ''' ----------------------------------------------------------------------------------------------------
  302.        Private Shared Function GetFramesFromImage(ByVal img As Image) As List(Of Bitmap)
  303.  
  304.            Dim imgs As New List(Of Bitmap)
  305.            Dim frameCount As Integer = img.GetFrameCount(FrameDimension.Time)
  306.  
  307.            For i As Integer = 0 To (frameCount - 1)
  308.                img.SelectActiveFrame(FrameDimension.Time, i)
  309.                imgs.Add(New Bitmap(img)) ' Deep copy of the frame (only the frame).
  310.            Next
  311.  
  312.            Return imgs
  313.  
  314.        End Function
  315.  
  316. #End Region
  317.  
  318.    End Class
  319.  
  320. #End Region
  321.  

Ejemplos de uso:
Código
  1. Dim pcb As PictureBox = Me.PictureBox1
  2. Dim gif As New GIF("C:\File.gif")
  3.  
  4. Do Until gif.EndOfFrames ' Iterate frames until the end of frame count.
  5.  
  6.    ' Free previous Bitmap object.
  7.    If (pcb.Image IsNot Nothing) Then
  8.        pcb.Image.Dispose()
  9.        pcb.Image = Nothing
  10.    End If
  11.  
  12.    pcb.Image = gif.NextFrame()
  13.    Thread.Sleep(60) ' Simulate a FPS thingy.
  14.    Application.DoEvents()
  15.  
  16.    If (gif.EndOfFrames) Then
  17.        ' Set active frame to 0 for infinite loop:
  18.        gif.ActiveFrameIndex = 0
  19.    End If
  20.  
  21. Loop

Nótese que el método GIF.GetFrames() devuelve una colección de Bitmaps con todos los frames de la imagen GIF. Las posibilidades son infinitas con esta colección, podemos añadir, editar o eliminar frames para crear un nuevo GIF, o simplemente mostrar la secuencia de frames...

¡Saludos!
« Última modificación: 2 Abril 2017, 22:40 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #504 en: 7 Abril 2017, 06:16 am »

Determinar si dos colores son similares

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Determines whether two colors are similar.
  4.    ''' <para></para>
  5.    ''' It compares the RGB channel differences to match inside the range of the specified tolerance values.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="color1">
  9.    ''' The first color to compare.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="color2">
  13.    ''' The second color to compare.
  14.    ''' </param>
  15.    '''
  16.    ''' <param name="toleranceR">
  17.    ''' The tolerance of the Red color channel.
  18.    ''' From 0 to 255.
  19.    ''' </param>
  20.    '''
  21.    ''' <param name="toleranceG">
  22.    ''' The tolerance of the Green color channel.
  23.    ''' From 0 to 255.
  24.    ''' </param>
  25.    '''
  26.    ''' <param name="toleranceB">
  27.    ''' The tolerance of the Blue color channel.
  28.    ''' From 0 to 255.
  29.    ''' </param>
  30.    ''' ----------------------------------------------------------------------------------------------------
  31.    ''' <returns>
  32.    ''' <see langword="True"/> if the colors are similar,
  33.    ''' this means the RGB differences matches inside the range of the specified tolerance value,
  34.    ''' <see langword="False"/> otherwise.
  35.    ''' </returns>
  36.    ''' ----------------------------------------------------------------------------------------------------
  37.    Public Shared Function IsColorSimilar(ByVal color1 As Color, ByVal color2 As Color,
  38.                                          ByVal toleranceR As Byte, ByVal toleranceG As Byte, ByVal toleranceB As Byte) As Boolean
  39.  
  40.        Return Math.Abs(CInt(color1.R) - color2.R) <= toleranceR AndAlso
  41.               Math.Abs(CInt(color1.G) - color2.G) <= toleranceG AndAlso
  42.               Math.Abs(CInt(color1.B) - color2.B) <= toleranceB
  43.  
  44.    End Function

Modo de empleo:
Código
  1. Dim areSimilar As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 1),
  2.                                           toleranceR:=0, toleranceG:=0, toleranceB:=1)
  3. ' Result: True

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Determines whether two colors are similar.
  4.    ''' <para></para>
  5.    ''' It compares the RGB channel difference to match inside the range of the specified tolerance value.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="color1">
  9.    ''' The first color to compare.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="color2">
  13.    ''' The second color to compare.
  14.    ''' </param>
  15.    '''
  16.    ''' <param name="tolerance">
  17.    ''' The global tolerance of the RGB color channels.
  18.    ''' From 0 to 255.
  19.    ''' </param>
  20.    ''' ----------------------------------------------------------------------------------------------------
  21.    ''' <returns>
  22.    ''' <see langword="True"/> if the colors are similar,
  23.    ''' this means the RGB differences matches inside the range of the specified tolerance value,
  24.    ''' <see langword="False"/> otherwise.
  25.    ''' </returns>
  26.    ''' ----------------------------------------------------------------------------------------------------
  27.    Public Shared Function IsColorSimilar(ByVal color1 As Color, ByVal color2 As Color, ByVal tolerance As Byte) As Boolean
  28.  
  29.        Return (Math.Abs(CInt(color1.R) - color2.R) +
  30.                Math.Abs(CInt(color1.G) - color2.G) +
  31.                Math.Abs(CInt(color1.B) - color2.B)) <= tolerance
  32.  
  33.    End Function

Modo de empleo :

Código
  1. Dim result1 As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 1), tolerance:=1)
  2. ' Result: True
  3. '  Logic: Blue channel difference = 1, which is equal than the specified tolerance value.
  4.  
  5. Dim result2 As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 1, 1), tolerance:=1)
  6. ' Result: False
  7. '  Logic: Red channel + Blue channel differences = 2, which is a bigger value than the specified tolerance value.



Voltear una imagen

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Specifies a flip type operation to perform for an image.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. Public Enum FlipType As Integer
  7.  
  8.    ''' <summary>
  9.    ''' Horizontal flip.
  10.    ''' </summary>
  11.    Horizontal = 1
  12.  
  13.    ''' <summary>
  14.    ''' Vertical flip.
  15.    ''' </summary>
  16.    Vertical = 2
  17.  
  18.    ''' <summary>
  19.    ''' Both a horizontal and vertical flip.
  20.    ''' </summary>
  21.    Both = 3
  22.  
  23. End Enum
  24.  
  25. public module ImageExtensions
  26.  
  27. ''' ----------------------------------------------------------------------------------------------------
  28. ''' <summary>
  29. ''' Flips an <see cref="Image"/>.
  30. ''' </summary>
  31. ''' ----------------------------------------------------------------------------------------------------
  32. ''' <param name="sender">
  33. ''' The source <see cref="Image"/>.
  34. ''' </param>
  35. '''
  36. ''' <param name="fliptype">
  37. ''' The flip type operation to perform.
  38. ''' </param>
  39. ''' ----------------------------------------------------------------------------------------------------
  40. ''' <returns>
  41. ''' The resulting <see cref="Image"/>.
  42. ''' </returns>
  43. ''' ----------------------------------------------------------------------------------------------------
  44. <Extension>
  45. <DebuggerStepThrough>
  46. <EditorBrowsable(EditorBrowsableState.Always)>
  47. Public Function Flip(ByVal sender As Image, ByVal fliptype As FlipType) As Image
  48.  
  49.    Dim flippedImage As New Bitmap(sender.Width, sender.Height, sender.PixelFormat)
  50.  
  51.    Using g As Graphics = Graphics.FromImage(flippedImage)
  52.  
  53.        Dim m As Matrix = Nothing
  54.        Select Case fliptype
  55.            Case FlipType.Horizontal
  56.                m = New Matrix(-1, 0, 0, 1, 0, 0)
  57.                m.Translate(flippedImage.Width, 0, MatrixOrder.Append)
  58.  
  59.            Case FlipType.Vertical
  60.                m = New Matrix(1, 0, 0, -1, 0, 0)
  61.                m.Translate(0, flippedImage.Height, MatrixOrder.Append)
  62.  
  63.            Case FlipType.Both
  64.                m = New Matrix(-1, 0, 0, -1, 0, 0)
  65.                m.Translate(flippedImage.Width, flippedImage.Height, MatrixOrder.Append)
  66.        End Select
  67.  
  68.        ' Draw
  69.        g.Transform = m
  70.        g.DrawImage(sender, 0, 0)
  71.  
  72.        'clean up
  73.        m.Dispose()
  74.    End Using
  75.  
  76.    Return flippedImage
  77.  
  78. End Function
  79.  
  80. end module

Modo de empleo:

Código
  1. dim img as image = image.fromfile("C:\file.png")
  2. dim flipped as image=  imf.Flip(FlipType.Vertical)



Cifrado XOR

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Encrypts or decrypts a string using XOR algorithm.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <param name="text">
  7. ''' The text to encrypt.
  8. ''' </param>
  9. '''
  10. ''' <param name="key">
  11. ''' The key to use for encryption of decryption.
  12. ''' </param>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <returns>
  15. ''' The encrypted string.
  16. ''' </returns>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. <DebuggerStepThrough>
  19. Public Shared Function XorEncryptOrDecrypt(ByVal text As String, ByVal key As Integer) As String
  20.  
  21.    Dim sb As New StringBuilder(text.Length, text.Length)
  22.    For Each c As Char In text
  23.        ' Get the ASCII value of the character.
  24.        Dim charValue As Integer = Convert.ToInt32(c)
  25.        ' XOR the value.
  26.        charValue = (charValue Xor key)
  27.        ' Convert back to string.
  28.        sb.Append(Char.ConvertFromUtf32(charValue))
  29.    Next
  30.  
  31.    Return sb.ToString()
  32.  
  33. End Function

Modo de empleo:
Código
  1. Dim str As String = "Hello World"
  2. Dim encrypted As String = XorEncryptOrDecrypt(str, 1)       ' Result: "Idmmn!Vnsme"
  3. Dim decrypted As String = XorEncryptOrDecrypt(encrypted, 1) ' Result: "Hello World"



Obtener un array con los bytes del archivo de la aplicación actual

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets the bytes of the local file that points to the running assembly.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <value>
  7. ''' A <see cref="Byte()"/> array containing the bytes of the local file that points to the running assembly.
  8. ''' </value>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. Public Shared ReadOnly Property SelfBytes As Byte()
  11.    <DebuggerStepThrough>
  12.    Get
  13.        Using fs As FileStream = File.OpenRead(System.Windows.Forms.Application.ExecutablePath)
  14.            Dim exeBytes As Byte() = New Byte(CInt(fs.Length - 1)) {}
  15.            fs.Read(exeBytes, 0, exeBytes.Length)
  16.            Return exeBytes
  17.        End Using
  18.    End Get
  19. End Property

Modo de empleo:
Código
  1. Dim selfBytes As Byte() = SelfBytes()



Obtener recursos embedidos en un ensamblado .NET

Código
  1. Partial Public NotInheritable Class ResourceUtil
  2.  
  3.    ''' ----------------------------------------------------------------------------------------------------
  4.    ''' <summary>
  5.    ''' Gets an embedded resource in the specified <see cref="Assembly"/>.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="name">
  9.    ''' The name of the resource.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="ass">
  13.    ''' The <see cref="Assembly"/> to look for the resource.
  14.    ''' </param>
  15.    ''' ----------------------------------------------------------------------------------------------------
  16.    ''' <returns>
  17.    ''' A <see cref="Byte()"/> array containing the bytes of the embedded resource.
  18.    ''' </returns>
  19.    ''' ----------------------------------------------------------------------------------------------------
  20.    Public Shared Function GetEmbeddedResource(ByVal name As String, ByVal ass As Assembly) As Byte()
  21.  
  22.        name = ResourceUtil.FormatResourceName(name, ass)
  23.  
  24.        Using resx As Stream = ass.GetManifestResourceStream(name)
  25.  
  26.            If (resx Is Nothing) Then
  27.                Throw New Exception("Resource not found in the specified .NET assembly.")
  28.  
  29.            Else
  30.                Dim content As Byte() = New Byte(CInt(resx.Length - 1)) {}
  31.                resx.Read(content, 0, content.Length)
  32.                Return content
  33.  
  34.            End If
  35.  
  36.        End Using
  37.  
  38.    End Function
  39.  
  40.    ''' ----------------------------------------------------------------------------------------------------
  41.    ''' <summary>
  42.    ''' Gets an embedded resource in the calling assembly.
  43.    ''' </summary>
  44.    ''' ----------------------------------------------------------------------------------------------------
  45.    ''' <param name="name">
  46.    ''' The name of the resource.
  47.    ''' </param>
  48.    ''' ----------------------------------------------------------------------------------------------------
  49.    ''' <returns>
  50.    ''' A <see cref="Byte()"/> array containing the bytes of the embedded resource.
  51.    ''' </returns>
  52.    ''' ----------------------------------------------------------------------------------------------------
  53.    Public Shared Function GetEmbeddedResource(ByVal name As String) As Byte()
  54.  
  55.        Return ResourceUtil.GetEmbeddedResource(name, Assembly.GetCallingAssembly())
  56.  
  57.    End Function
  58.  
  59.    ''' ----------------------------------------------------------------------------------------------------
  60.    ''' <summary>
  61.    ''' Gets an embedded resource of type <see cref="String"/> in the specified <see cref="Assembly"/>.
  62.    ''' </summary>
  63.    ''' ----------------------------------------------------------------------------------------------------
  64.    ''' <param name="name">
  65.    ''' The name of the resource.
  66.    ''' </param>
  67.    '''
  68.    ''' <param name="ass">
  69.    ''' The <see cref="Assembly"/> to look for the resource.
  70.    ''' </param>
  71.    ''' ----------------------------------------------------------------------------------------------------
  72.    ''' <returns>
  73.    ''' The embedded resource as <see cref="String"/>.
  74.    ''' </returns>
  75.    ''' ----------------------------------------------------------------------------------------------------
  76.    Public Shared Function GetEmbeddedResourceAsString(ByVal name As String, ByVal ass As Assembly, Optional ByVal enc As Encoding = Nothing) As String
  77.  
  78.        If (enc Is Nothing) Then
  79.            enc = Encoding.Default
  80.        End If
  81.  
  82.        name = ResourceUtil.FormatResourceName(name, ass)
  83.  
  84.        Using resx As Stream = ass.GetManifestResourceStream(name)
  85.  
  86.            If (resx Is Nothing) Then
  87.                Throw New Exception("Resource not found in the specified .NET assembly.")
  88.            Else
  89.                Using reader As New StreamReader(resx, enc)
  90.                    Return reader.ReadToEnd()
  91.                End Using
  92.            End If
  93.  
  94.        End Using
  95.  
  96.    End Function
  97.  
  98.    ''' ----------------------------------------------------------------------------------------------------
  99.    ''' <summary>
  100.    ''' Gets an embedded resource of type <see cref="String"/> in the calling assembly.
  101.    ''' </summary>
  102.    ''' ----------------------------------------------------------------------------------------------------
  103.    ''' <param name="name">
  104.    ''' The name of the resource.
  105.    ''' </param>
  106.    ''' ----------------------------------------------------------------------------------------------------
  107.    ''' <returns>
  108.    ''' The embedded resource as <see cref="String"/>.
  109.    ''' </returns>
  110.    ''' ----------------------------------------------------------------------------------------------------
  111.    Public Shared Function GetEmbeddedResourceAsString(ByVal name As String, Optional ByVal enc As Encoding = Nothing) As String
  112.  
  113.        Return ResourceUtil.GetEmbeddedResourceAsString(name, Assembly.GetCallingAssembly(), enc)
  114.  
  115.    End Function
  116.  
  117.    ''' ----------------------------------------------------------------------------------------------------
  118.    ''' <summary>
  119.    ''' Gets an embedded resource of type <see cref="Image"/> in the specified <see cref="Assembly"/>.
  120.    ''' </summary>
  121.    ''' ----------------------------------------------------------------------------------------------------
  122.    ''' <param name="name">
  123.    ''' The name of the resource.
  124.    ''' </param>
  125.    '''
  126.    ''' <param name="ass">
  127.    ''' The <see cref="Assembly"/> to look for the resource.
  128.    ''' </param>
  129.    ''' ----------------------------------------------------------------------------------------------------
  130.    ''' <returns>
  131.    ''' The embedded resource as <see cref="Image"/>.
  132.    ''' </returns>
  133.    ''' ----------------------------------------------------------------------------------------------------
  134.    Public Shared Function GetEmbeddedResourceAsImage(ByVal name As String, ByVal ass As Assembly) As Image
  135.  
  136.        name = ResourceUtil.FormatResourceName(name, ass)
  137.  
  138.        Using resx As Stream = ass.GetManifestResourceStream(name)
  139.  
  140.            If (resx Is Nothing) Then
  141.                Throw New Exception("Resource not found in the specified .NET assembly.")
  142.            Else
  143.                Using ms As New MemoryStream()
  144.                    resx.CopyTo(ms)
  145.                    Return Image.FromStream(ms)
  146.                End Using
  147.  
  148.            End If
  149.  
  150.        End Using
  151.  
  152.    End Function
  153.  
  154.    ''' ----------------------------------------------------------------------------------------------------
  155.    ''' <summary>
  156.    ''' Gets an embedded resource of type <see cref="Image"/> in the calling assembly.
  157.    ''' </summary>
  158.    ''' ----------------------------------------------------------------------------------------------------
  159.    ''' <param name="name">
  160.    ''' The name of the resource.
  161.    ''' </param>
  162.    ''' ----------------------------------------------------------------------------------------------------
  163.    ''' <returns>
  164.    ''' The embedded resource as <see cref="Image"/>.
  165.    ''' </returns>
  166.    ''' ----------------------------------------------------------------------------------------------------
  167.    Public Shared Function GetEmbeddedResourceAsImage(ByVal name As String) As Image
  168.  
  169.        Return ResourceUtil.GetEmbeddedResourceAsImage(name, Assembly.GetCallingAssembly())
  170.  
  171.    End Function
  172.  
  173.    ''' ----------------------------------------------------------------------------------------------------
  174.    ''' <summary>
  175.    ''' Formats a resource name.
  176.    ''' </summary>
  177.    ''' ----------------------------------------------------------------------------------------------------
  178.    ''' <param name="name">
  179.    ''' The name of the resource.
  180.    ''' </param>
  181.    '''
  182.    ''' <param name="ass">
  183.    ''' The assembly that contains the resource.
  184.    ''' </param>
  185.    ''' ----------------------------------------------------------------------------------------------------
  186.    ''' <returns>
  187.    ''' The resulting formatted resource name.
  188.    ''' </returns>
  189.    ''' ----------------------------------------------------------------------------------------------------
  190.    Private Shared Function FormatResourceName(ByVal name As String, ByVal ass As Assembly) As String
  191.  
  192.        Return String.Format("{0}.{1}", ass.GetName().Name, name.Replace(" ", "_").
  193.                                                                 Replace("\", ".").
  194.                                                                 Replace("/", "."))
  195.  
  196.    End Function
  197.  
  198. End Class

Ejemplo de uso para la aplicación actual:
Código
  1. Dim data As Byte() = GetEmbeddedResource("file.txt")
  2. Dim dataAsString As String = Encoding.Default.GetString(data)
  3.  
  4. Dim str As String = GetEmbeddedResourceAsString("file.txt", Encoding.Default)
  5.  
  6. Dim img As Image = GetEmbeddedResourceAsImage("file.png")

Ejemplo de uso con un ensamblado específico:
Código
  1. Dim data As Byte() = GetEmbeddedResource("file.txt", Assembly.GetCallingAssembly())
  2. Dim dataAsString As String = Encoding.Default.GetString(data)
  3.  
  4. Dim str As String = GetEmbeddedResourceAsString("file.txt", Assembly.GetCallingAssembly(), Encoding.Default)
  5.  
  6. Dim img As Image = GetEmbeddedResourceAsImage("file.png", Assembly.GetCallingAssembly())



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework ElektroKit.
« Última modificación: 7 Abril 2017, 06:26 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #505 en: 13 Abril 2017, 12:50 pm »

Pausar la ejecución de la consola hasta que se pulse cierta tecla...

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Pause the console execution Indefinitely until any key is pressed.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. <DebuggerStepThrough>
  7. Public Shared Sub Pause()
  8.    Console.ReadKey(intercept:=True)
  9. End Sub
  10.  
  11. ''' ----------------------------------------------------------------------------------------------------
  12. ''' <summary>
  13. ''' Pause the console execution Indefinitely until the specified key is pressed.
  14. ''' </summary>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="key">
  17. ''' The key to wait for.
  18. ''' </param>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. <DebuggerStepThrough>
  21. Public Shared Sub Pause(ByVal key As Keys)
  22.  
  23.    Dim keyInfo As ConsoleKeyInfo
  24.  
  25.    Do Until (keyInfo.Key = key)
  26.        keyInfo = Console.ReadKey(intercept:=True)
  27.    Loop
  28.  
  29. End Sub

Modo de empleo:
Código
  1. Console.WriteLine("Press any key to exit...")
  2. Pause()
  3. Environment.Exit(0)

Código
  1. Dim key As Keys = Keys.Enter
  2. Dim keyName As String = [Enum].GetName(GetType(Keys), key)
  3.  
  4. Console.WriteLine(String.Format("Press '{0}' key to continue...", keyName))
  5. Pause(key)
  6. Console.WriteLine("Well done.")
En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #506 en: 29 Abril 2017, 20:00 pm »

Un puñado de funciones para extender las posibilidades de la función built-in System.IO.Path.GetTempFileName()

Modo de empleo:

Código
  1. Dim tmpFile1 As FileInfo = GetTempFile()
  2. Dim tmpFile2 As FileInfo = GetTempFile("txt")
  3. Dim tmpFile3 As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData)
  4. Dim tmpFile4 As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData, "txt")
  5. Dim tmpFile5 As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"))
  6. Dim tmpFile6 As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"), "txt")
  7. Dim tmpFile7 As FileInfo = GetTempFile("C:\Folder\", "txt")

Código
  1. Dim tmpFilePath1 As String = GetTempFileName()
  2. Dim tmpFilePath2 As String = GetTempFileName("txt")
  3. Dim tmpFilePath3 As String = GetTempFileName(SpecialFolder.LocalApplicationData)
  4. Dim tmpFilePath4 As String = GetTempFileName(SpecialFolder.LocalApplicationData, "txt")
  5. Dim tmpFilePath5 As String = GetTempFileName(New DirectoryInfo("C:\Folder\"))
  6. Dim tmpFilePath6 As String = GetTempFileName(New DirectoryInfo("C:\Folder\"), "txt")
  7. Dim tmpFilePath7 As String = GetTempFileName("C:\Folder\", "txt")

Código fuente:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder
  4. ''' and returns the file.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <example> This is a code example.
  8. ''' <code>
  9. ''' Dim tmpFile As FileInfo = GetTempFile()
  10. ''' Console.WriteLine(tmpFile.FullName)
  11. ''' </code>
  12. ''' </example>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <returns>
  15. ''' The resulting <see cref="FileInfo"/>.
  16. ''' </returns>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. <DebuggerStepThrough>
  19. Public Shared Function GetTempFile() As FileInfo
  20.  
  21.    Return New FileInfo(Path.GetTempFileName())
  22.  
  23. End Function
  24.  
  25. ''' ----------------------------------------------------------------------------------------------------
  26. ''' <summary>
  27. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  28. ''' and returns the file.
  29. ''' </summary>
  30. ''' ----------------------------------------------------------------------------------------------------
  31. ''' <example> This is a code example.
  32. ''' <code>
  33. ''' Dim tmpFile As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData)
  34. ''' Console.WriteLine(tmpFile.FullName)
  35. ''' </code>
  36. ''' </example>
  37. ''' ----------------------------------------------------------------------------------------------------
  38. ''' <param name="folder">
  39. ''' The folder where to create the temporary file.
  40. ''' </param>
  41. ''' ----------------------------------------------------------------------------------------------------
  42. ''' <returns>
  43. ''' The resulting <see cref="FileInfo"/>.
  44. ''' </returns>
  45. ''' ----------------------------------------------------------------------------------------------------
  46. <DebuggerStepThrough>
  47. Public Shared Function GetTempFile(ByVal folder As SpecialFolder) As FileInfo
  48.  
  49.    Return GetTempFile(Environment.GetFolderPath(folder), "tmp")
  50.  
  51. End Function
  52.  
  53. ''' ----------------------------------------------------------------------------------------------------
  54. ''' <summary>
  55. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  56. ''' and returns the file.
  57. ''' </summary>
  58. ''' ----------------------------------------------------------------------------------------------------
  59. ''' <example> This is a code example.
  60. ''' <code>
  61. ''' Dim tmpFile As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"))
  62. ''' Console.WriteLine(tmpFile.FullName)
  63. ''' </code>
  64. ''' </example>
  65. ''' ----------------------------------------------------------------------------------------------------
  66. ''' <param name="dir">
  67. ''' The folder where to create the temporary file.
  68. ''' </param>
  69. ''' ----------------------------------------------------------------------------------------------------
  70. ''' <returns>
  71. ''' The resulting <see cref="FileInfo"/>.
  72. ''' </returns>
  73. ''' ----------------------------------------------------------------------------------------------------
  74. <DebuggerStepThrough>
  75. Public Shared Function GetTempFile(ByVal dir As DirectoryInfo) As FileInfo
  76.  
  77.    Return GetTempFile(dir.FullName, "tmp")
  78.  
  79. End Function
  80.  
  81. ''' ----------------------------------------------------------------------------------------------------
  82. ''' <summary>
  83. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder with the specified file extension
  84. ''' and returns the file.
  85. ''' </summary>
  86. ''' ----------------------------------------------------------------------------------------------------
  87. ''' <example> This is a code example.
  88. ''' <code>
  89. ''' Dim tmpFile As FileInfo = GetTempFile("txt")
  90. ''' Console.WriteLine(tmpFile.FullName)
  91. ''' </code>
  92. ''' </example>
  93. ''' ----------------------------------------------------------------------------------------------------
  94. ''' <param name="extension">
  95. ''' The file extension to assign to the temporary file.
  96. ''' </param>
  97. ''' ----------------------------------------------------------------------------------------------------
  98. ''' <returns>
  99. ''' The resulting <see cref="FileInfo"/>.
  100. ''' </returns>
  101. ''' ----------------------------------------------------------------------------------------------------
  102. ''' <exception cref="ArgumentNullException">
  103. ''' extension
  104. ''' </exception>
  105. ''' ----------------------------------------------------------------------------------------------------
  106. <DebuggerStepThrough>
  107. Public Shared Function GetTempFile(ByVal extension As String) As FileInfo
  108.  
  109.    Return GetTempFile(Environment.GetFolderPath(SpecialFolder.LocalApplicationData), extension)
  110.  
  111. End Function
  112.  
  113. ''' ----------------------------------------------------------------------------------------------------
  114. ''' <summary>
  115. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  116. ''' and returns the file.
  117. ''' </summary>
  118. ''' ----------------------------------------------------------------------------------------------------
  119. ''' <example> This is a code example.
  120. ''' <code>
  121. ''' Dim tmpFile As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData, "txt")
  122. ''' Console.WriteLine(tmpFile.FullName)
  123. ''' </code>
  124. ''' </example>
  125. ''' ----------------------------------------------------------------------------------------------------
  126. ''' <param name="folder">
  127. ''' The folder where to create the temporary file.
  128. ''' </param>
  129. '''
  130. ''' <param name="extension">
  131. ''' The file extension to assign to the temporary file.
  132. ''' </param>
  133. ''' ----------------------------------------------------------------------------------------------------
  134. ''' <returns>
  135. ''' The resulting <see cref="FileInfo"/>.
  136. ''' </returns>
  137. ''' ----------------------------------------------------------------------------------------------------
  138. ''' <exception cref="ArgumentNullException">
  139. ''' extension
  140. ''' </exception>
  141. ''' ----------------------------------------------------------------------------------------------------
  142. <DebuggerStepThrough>
  143. Public Shared Function GetTempFile(ByVal folder As SpecialFolder, ByVal extension As String) As FileInfo
  144.  
  145.    Return GetTempFile(Environment.GetFolderPath(folder), extension)
  146.  
  147. End Function
  148.  
  149. ''' ----------------------------------------------------------------------------------------------------
  150. ''' <summary>
  151. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  152. ''' and returns the file.
  153. ''' </summary>
  154. ''' ----------------------------------------------------------------------------------------------------
  155. ''' <example> This is a code example.
  156. ''' <code>
  157. ''' Dim tmpFile As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"), "txt")
  158. ''' Console.WriteLine(tmpFile.FullName)
  159. ''' </code>
  160. ''' </example>
  161. ''' ----------------------------------------------------------------------------------------------------
  162. ''' <param name="dir">
  163. ''' The folder where to create the temporary file.
  164. ''' </param>
  165. '''
  166. ''' <param name="extension">
  167. ''' The file extension to assign to the temporary file.
  168. ''' </param>
  169. ''' ----------------------------------------------------------------------------------------------------
  170. ''' <returns>
  171. ''' The resulting <see cref="FileInfo"/>.
  172. ''' </returns>
  173. ''' ----------------------------------------------------------------------------------------------------
  174. ''' <exception cref="ArgumentNullException">
  175. ''' extension
  176. ''' </exception>
  177. ''' ----------------------------------------------------------------------------------------------------
  178. <DebuggerStepThrough>
  179. Public Shared Function GetTempFile(ByVal dir As DirectoryInfo, ByVal extension As String) As FileInfo
  180.  
  181.    Return GetTempFile(dir.FullName, extension)
  182.  
  183. End Function
  184.  
  185. ''' ----------------------------------------------------------------------------------------------------
  186. ''' <summary>
  187. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  188. ''' and returns the file.
  189. ''' </summary>
  190. ''' ----------------------------------------------------------------------------------------------------
  191. ''' <example> This is a code example.
  192. ''' <code>
  193. ''' Dim tmpFile As FileInfo = GetTempFile("C:\Folder\", "txt")
  194. ''' Console.WriteLine(tmpFile.FullName)
  195. ''' </code>
  196. ''' </example>
  197. ''' ----------------------------------------------------------------------------------------------------
  198. ''' <param name="dirPath">
  199. ''' The full path of the folder where to create the temporary file.
  200. ''' </param>
  201. '''
  202. ''' <param name="extension">
  203. ''' The file extension to assign to the temporary file.
  204. ''' </param>
  205. ''' ----------------------------------------------------------------------------------------------------
  206. ''' <returns>
  207. ''' The resulting <see cref="FileInfo"/>.
  208. ''' </returns>
  209. ''' ----------------------------------------------------------------------------------------------------
  210. ''' <exception cref="ArgumentNullException">
  211. ''' dirPath or extension
  212. ''' </exception>
  213. ''' ----------------------------------------------------------------------------------------------------
  214. <DebuggerStepThrough>
  215. Public Shared Function GetTempFile(ByVal dirPath As String, ByVal extension As String) As FileInfo
  216.  
  217.    If String.IsNullOrWhiteSpace(dirPath) Then
  218.        Throw New ArgumentNullException("dirPath")
  219.  
  220.    ElseIf String.IsNullOrWhiteSpace(extension) Then
  221.        Throw New ArgumentNullException("extension")
  222.  
  223.    Else
  224.        Dim dir As New DirectoryInfo(dirPath)
  225.        If Not (dir.Exists) Then
  226.            Try
  227.                dir.Create()
  228.            Catch ex As Exception
  229.                Throw
  230.                Return Nothing
  231.            End Try
  232.        End If
  233.  
  234.        Dim tmpFile As FileInfo = Nothing
  235.        Dim newFilePath As String
  236.        Dim defaultFolderPath As String = Environment.GetFolderPath(SpecialFolder.LocalApplicationData)
  237.        Dim defaultFileExtension As String = "tmp"
  238.        Do
  239.            If (tmpFile IsNot Nothing) AndAlso (tmpFile.Exists) Then
  240.                tmpFile.Delete()
  241.            End If
  242.            tmpFile = New FileInfo(Path.GetTempFileName())
  243.  
  244.            If Not (dir.FullName.Equals(defaultFolderPath, StringComparison.OrdinalIgnoreCase)) Then
  245.                newFilePath = Path.Combine(dir.FullName, tmpFile.Name)
  246.            Else
  247.                newFilePath = tmpFile.FullName
  248.            End If
  249.  
  250.            If Not (extension.Equals(defaultFileExtension, StringComparison.OrdinalIgnoreCase)) Then
  251.                newFilePath = Path.ChangeExtension(newFilePath, extension)
  252.            End If
  253.  
  254.        Loop Until (newFilePath.Equals(tmpFile.FullName, StringComparison.OrdinalIgnoreCase)) OrElse Not File.Exists(newFilePath)
  255.  
  256.        tmpFile.MoveTo(newFilePath)
  257.        tmpFile.Refresh()
  258.  
  259.        Return tmpFile
  260.  
  261.    End If
  262.  
  263. End Function
  264.  
  265. ''' ----------------------------------------------------------------------------------------------------
  266. ''' <summary>
  267. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder
  268. ''' and returns the file path.
  269. ''' </summary>
  270. ''' ----------------------------------------------------------------------------------------------------
  271. ''' <example> This is a code example.
  272. ''' <code>
  273. ''' Dim tmpFile As String = GetTempFileName()
  274. ''' Console.WriteLine(tmpFile)
  275. ''' </code>
  276. ''' </example>
  277. ''' ----------------------------------------------------------------------------------------------------
  278. ''' <returns>
  279. ''' The full path of the temporary file.
  280. ''' </returns>
  281. ''' ----------------------------------------------------------------------------------------------------
  282. <DebuggerStepThrough>
  283. Public Shared Function GetTempFileName() As String
  284.  
  285.    Return Path.GetTempFileName()
  286.  
  287. End Function
  288.  
  289. ''' ----------------------------------------------------------------------------------------------------
  290. ''' <summary>
  291. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  292. ''' and returns the file path.
  293. ''' </summary>
  294. ''' ----------------------------------------------------------------------------------------------------
  295. ''' <example> This is a code example.
  296. ''' <code>
  297. ''' Dim tmpFile As String = GetTempFileName(SpecialFolder.LocalApplicationData)
  298. ''' Console.WriteLine(tmpFile)
  299. ''' </code>
  300. ''' </example>
  301. ''' ----------------------------------------------------------------------------------------------------
  302. ''' <param name="folder">
  303. ''' The folder where to create the temporary file.
  304. ''' </param>
  305. ''' ----------------------------------------------------------------------------------------------------
  306. ''' <returns>
  307. ''' The full path of the temporary file.
  308. ''' </returns>
  309. ''' ----------------------------------------------------------------------------------------------------
  310. <DebuggerStepThrough>
  311. Public Shared Function GetTempFileName(ByVal folder As SpecialFolder) As String
  312.  
  313.    Return GetTempFile(Environment.GetFolderPath(folder), "tmp").FullName
  314.  
  315. End Function
  316.  
  317. ''' ----------------------------------------------------------------------------------------------------
  318. ''' <summary>
  319. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  320. ''' and returns the file path.
  321. ''' </summary>
  322. ''' ----------------------------------------------------------------------------------------------------
  323. ''' <example> This is a code example.
  324. ''' <code>
  325. ''' Dim tmpFile As String = GetTempFileName(New DirectoryInfo("C:\Folder\"))
  326. ''' Console.WriteLine(tmpFile)
  327. ''' </code>
  328. ''' </example>
  329. ''' ----------------------------------------------------------------------------------------------------
  330. ''' <param name="dir">
  331. ''' The folder where to create the temporary file.
  332. ''' </param>
  333. ''' ----------------------------------------------------------------------------------------------------
  334. ''' <returns>
  335. ''' The full path of the temporary file.
  336. ''' </returns>
  337. ''' ----------------------------------------------------------------------------------------------------
  338. <DebuggerStepThrough>
  339. Public Shared Function GetTempFileName(ByVal dir As DirectoryInfo) As String
  340.  
  341.    Return GetTempFile(dir.FullName, "tmp").FullName
  342.  
  343. End Function
  344.  
  345. ''' ----------------------------------------------------------------------------------------------------
  346. ''' <summary>
  347. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder with the specified file extension
  348. ''' and returns the file path.
  349. ''' </summary>
  350. ''' ----------------------------------------------------------------------------------------------------
  351. ''' <example> This is a code example.
  352. ''' <code>
  353. ''' Dim tmpFile As String = GetTempFileName("txt")
  354. ''' Console.WriteLine(tmpFile)
  355. ''' </code>
  356. ''' </example>
  357. ''' ----------------------------------------------------------------------------------------------------
  358. ''' <param name="extension">
  359. ''' The file extension to assign to the temporary file.
  360. ''' </param>
  361. ''' ----------------------------------------------------------------------------------------------------
  362. ''' <returns>
  363. ''' The full path of the temporary file.
  364. ''' </returns>
  365. ''' ----------------------------------------------------------------------------------------------------
  366. ''' <exception cref="ArgumentNullException">
  367. ''' extension
  368. ''' </exception>
  369. ''' ----------------------------------------------------------------------------------------------------
  370. <DebuggerStepThrough>
  371. Public Shared Function GetTempFileName(ByVal extension As String) As String
  372.  
  373.    Return GetTempFile(Environment.GetFolderPath(SpecialFolder.LocalApplicationData), extension).FullName
  374.  
  375. End Function
  376.  
  377. ''' ----------------------------------------------------------------------------------------------------
  378. ''' <summary>
  379. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  380. ''' and returns the file path.
  381. ''' </summary>
  382. ''' ----------------------------------------------------------------------------------------------------
  383. ''' <example> This is a code example.
  384. ''' <code>
  385. ''' Dim tmpFile As String = GetTempFileName(SpecialFolder.LocalApplicationData, "txt")
  386. ''' Console.WriteLine(tmpFile)
  387. ''' </code>
  388. ''' </example>
  389. ''' ----------------------------------------------------------------------------------------------------
  390. ''' <param name="folder">
  391. ''' The folder where to create the temporary file.
  392. ''' </param>
  393. '''
  394. ''' <param name="extension">
  395. ''' The file extension to assign to the temporary file.
  396. ''' </param>
  397. ''' ----------------------------------------------------------------------------------------------------
  398. ''' <returns>
  399. ''' The full path of the temporary file.
  400. ''' </returns>
  401. ''' ----------------------------------------------------------------------------------------------------
  402. ''' <exception cref="ArgumentNullException">
  403. ''' extension
  404. ''' </exception>
  405. ''' ----------------------------------------------------------------------------------------------------
  406. <DebuggerStepThrough>
  407. Public Shared Function GetTempFileName(ByVal folder As SpecialFolder, ByVal extension As String) As String
  408.  
  409.    Return GetTempFile(Environment.GetFolderPath(folder), extension).FullName
  410.  
  411. End Function
  412.  
  413. ''' ----------------------------------------------------------------------------------------------------
  414. ''' <summary>
  415. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  416. ''' and returns the file path.
  417. ''' </summary>
  418. ''' ----------------------------------------------------------------------------------------------------
  419. ''' <example> This is a code example.
  420. ''' <code>
  421. ''' Dim tmpFile As String = GetTempFileName(New DirectoryInfo("C:\Folder\"), "txt")
  422. ''' Console.WriteLine(tmpFile)
  423. ''' </code>
  424. ''' </example>
  425. ''' ----------------------------------------------------------------------------------------------------
  426. ''' <param name="dir">
  427. ''' The folder where to create the temporary file.
  428. ''' </param>
  429. '''
  430. ''' <param name="extension">
  431. ''' The file extension to assign to the temporary file.
  432. ''' </param>
  433. ''' ----------------------------------------------------------------------------------------------------
  434. ''' <returns>
  435. ''' The full path of the temporary file.
  436. ''' </returns>
  437. ''' ----------------------------------------------------------------------------------------------------
  438. ''' <exception cref="ArgumentNullException">
  439. ''' extension
  440. ''' </exception>
  441. ''' ----------------------------------------------------------------------------------------------------
  442. <DebuggerStepThrough>
  443. Public Shared Function GetTempFileName(ByVal dir As DirectoryInfo, ByVal extension As String) As String
  444.  
  445.    Return GetTempFile(dir.FullName, extension).FullName
  446.  
  447. End Function
  448.  
  449. ''' ----------------------------------------------------------------------------------------------------
  450. ''' <summary>
  451. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  452. ''' and returns the file path.
  453. ''' </summary>
  454. ''' ----------------------------------------------------------------------------------------------------
  455. ''' <example> This is a code example.
  456. ''' <code>
  457. ''' Dim tmpFile As String = GetTempFileName("C:\Folder\", "txt")
  458. ''' Console.WriteLine(tmpFile)
  459. ''' </code>
  460. ''' </example>
  461. ''' ----------------------------------------------------------------------------------------------------
  462. ''' <param name="dirPath">
  463. ''' The full path of the folder where to create the temporary file.
  464. ''' </param>
  465. '''
  466. ''' <param name="extension">
  467. ''' The file extension to assign to the temporary file.
  468. ''' </param>
  469. ''' ----------------------------------------------------------------------------------------------------
  470. ''' <returns>
  471. ''' The full path of the temporary file.
  472. ''' </returns>
  473. ''' ----------------------------------------------------------------------------------------------------
  474. ''' <exception cref="ArgumentNullException">
  475. ''' dirPath or extension
  476. ''' </exception>
  477. ''' ----------------------------------------------------------------------------------------------------
  478. <DebuggerStepThrough>
  479. Public Shared Function GetTempFileName(ByVal dirPath As String, ByVal extension As String) As String
  480.  
  481.    Return GetTempFile(dirPath, extension).FullName
  482.  
  483. End Function
  484.  
« Última modificación: 29 Abril 2017, 20:13 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #507 en: 6 Mayo 2017, 14:05 pm »

Método Application.DoEvents() perfeccionado

Muchos programadores de VB.NET a veces se encuentran en un escenario de programación en el que deben realizar una operación asincrónica, pero en lugar de implementar el modo correcto de programación asincrónica suelen llamar al método Application.DoEvents() con la intención de esperar a que dicha operación asincrónica termine y evitar el bloqueo en el hilo de la interfáz gráfica. Esto se suele hacer decorando la llamada a dicho método usando un búcle, por ejemplo:

Código
  1. Do While (condición)
  2.     Application.DoEvents()
  3. Loop

Sin embargo, hacer llamadas consecutivas a dicho método en un tiempo de intervalo demasiado corto (como en el búcle de arriba) causará un exceso muy importante de consumo de recursos en el equipo, puesto que basicamente lo que hace el método Application.DoEvents() es recibir, procesar, y despachar todos los mensajes pendientes en la cola, y no lo hace de forma selectiva, así que se procesan todos los mensajes de entrada/input, de dibujado/paint, los eventos, y etc, una y otra vez.

El método Application.DoEvents() tiene un propósito muy distinto del que realmente se le suele dar, y hay muchas formas de evitar tener que usar dicho método, pero no entraremos en esos temas ahora. Lo que explicaré será como poder mejorar el rendimiento y la responsabilidad de nuestra aplicación en un 90% al usar el método Application.DoEvents() cuando se le pretenda dar el uso que se ha explicado al principio.

Puesto que el método Application.DoEvents() se suele utilizar para aumentar la respuesta de la UI en una iteración intensiva, lo más apropiado para aumentar el rendimiento sería comprobar si existen mensajes de entrada (teclado o ratón) en la cola de mensajes del hilo de la UI antes de llamar a Application.DoEvents(). Y para ello existe una función Win32 a la que podemos recurrir presicamente para obtener un valor que nos diga si hay mensajes que se deban procesar o no los hay. La función se llama GetInputState, y en fin, todo esto que acabo de explicar quedaría implementado así:

Código
  1. ''' <summary>
  2. ''' Determines whether there are mouse-button or keyboard messages in the calling thread's message queue.
  3. ''' </summary>
  4. ''' <remarks>
  5. ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644935(v=vs.85).aspx"/>
  6. ''' </remarks>
  7. ''' <returns>
  8. ''' If the queue contains one or more new mouse-button or keyboard messages, the return value is <see langword="True"/>.
  9. ''' <para></para>
  10. ''' If there are no new mouse-button or keyboard messages in the queue, the return value is <see langword="False"/>.
  11. ''' </returns>
  12. <SuppressUnmanagedCodeSecurity>
  13. <DllImport("user32.dll", SetLastError:=False)>
  14. Private Shared Function GetInputState() As <MarshalAs(UnmanagedType.Bool)> Boolean
  15. End Function
  16.  
  17. ''' <summary>
  18. ''' Processes all Windows messages currently in the message queue of the application.
  19. ''' <para></para>
  20. ''' This method greatly boosts the performance of any application in difference to <see cref="Application.DoEvents()"/> method.
  21. ''' <para></para>
  22. ''' When calling <see cref="Application.DoEvents()"/> to make the UI responsive, it generally decreases application performance;
  23. ''' <para></para>
  24. ''' however, using this method, we make sure there is at least one input event (keyboard or mouse) that needs to be processed before internally calling <see cref="Application.DoEvents()"/>.
  25. ''' </summary>
  26. Public Shared Sub DoEvents()
  27.    If GetInputState() Then
  28.        Global.System.Windows.Forms.Application.DoEvents()
  29.    End If
  30. End Sub

Modo de empleo:
Código
  1. Do While True
  2.     DoEvents()
  3. Loop
« Última modificación: 6 Mayo 2017, 14:08 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #508 en: 1 Junio 2017, 17:51 pm »

¿Cómo obtener la clave de producto instalada en Windows, o instalar un archivo de licencia, o una clave de producto de Windows, y como desinstalar la clave o eliminarla del registro de Windows?.

He desarrollado la siguiente clase para poder efectuar algunas operacioens básicas de licencia y activación en Windows, como instalar un archivo de licencia, obtener la clave de producto instalada en Windows, instalar una nueva  clave de producto de Windows, desinstalarla o eliminarla del registro de Windows (tal como hace la herramienta slmgr.vbs /cpky de Microsoft).

Lo he probado en Windows 10 x64, sin problemas. En teoría debería funcionar desde Windows 7 para adelante, y versiones Windows Server desde la 2008 R2 para adelante.

Todo el código fuente está documentado y además los miembros incluyen ejemplos de uso documentados, no creo que haga falta explicar mucho más.

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 01-June-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Properties "
  9.  
  10. ' ProductId As String
  11. ' ProductKey As String
  12.  
  13. #End Region
  14.  
  15. #Region " Methods "
  16.  
  17. ' InstallLicense(String)
  18. ' InstallLicense(FileInfo)
  19.  
  20. ' InstallProductKey(String)
  21.  
  22. ' UninstallProductKey()
  23.  
  24. ' RemoveProductKeyFromRegistry()
  25.  
  26. ' RefreshLicenseStatus()
  27.  
  28. #End Region
  29.  
  30. #End Region
  31.  
  32. #Region " Option Statements "
  33.  
  34. Option Strict On
  35. Option Explicit On
  36. Option Infer Off
  37.  
  38. #End Region
  39.  
  40. #Region " Imports "
  41.  
  42. Imports Microsoft.Win32
  43.  
  44. Imports System.IO
  45. Imports System.Management
  46. Imports System.Runtime.InteropServices
  47.  
  48. ' Imports Elektro.Core.Types
  49.  
  50. #End Region
  51.  
  52. #Region " Licensing Util "
  53.  
  54. ' Namespace Tools.Shell
  55.  
  56.    ''' ----------------------------------------------------------------------------------------------------
  57.    ''' <summary>
  58.    ''' Contains Windows licensing related utilities.
  59.    ''' </summary>
  60.    ''' ----------------------------------------------------------------------------------------------------
  61.    Public NotInheritable Class Licensing ' : Inherits AestheticObject
  62.  
  63. #Region " Constructors "
  64.  
  65.        ''' ----------------------------------------------------------------------------------------------------
  66.        ''' <summary>
  67.        ''' Prevents a default instance of the <see cref="Licensing"/> class from being created.
  68.        ''' </summary>
  69.        ''' ----------------------------------------------------------------------------------------------------
  70.        <DebuggerNonUserCode>
  71.        Private Sub New()
  72.        End Sub
  73.  
  74. #End Region
  75.  
  76. #Region " Properties "
  77.  
  78.        ''' ----------------------------------------------------------------------------------------------------
  79.        ''' <summary>
  80.        ''' Gets the Windows product identifier of the current operating system.
  81.        ''' </summary>
  82.        ''' ----------------------------------------------------------------------------------------------------
  83.        ''' <example> This is a code example.
  84.        ''' <code>
  85.        ''' Dim productId As String = ProductId()
  86.        ''' Console.WriteLine(productId)
  87.        ''' </code>
  88.        ''' </example>
  89.        ''' ----------------------------------------------------------------------------------------------------
  90.        ''' <value>
  91.        ''' The Windows product identifier.
  92.        ''' </value>
  93.        ''' ----------------------------------------------------------------------------------------------------
  94.        Public Shared ReadOnly Property ProductId As String
  95.            <DebuggerStepThrough>
  96.            Get
  97.                Return Licensing.GetWindowsProductId()
  98.            End Get
  99.        End Property
  100.  
  101.        ''' ----------------------------------------------------------------------------------------------------
  102.        ''' <summary>
  103.        ''' Gets the Windows product key of the current operating system.
  104.        ''' <para></para>
  105.        ''' Note that the value could be <see langword="Nothing"/> in case of the product key was
  106.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  107.        ''' </summary>
  108.        ''' ----------------------------------------------------------------------------------------------------
  109.        ''' <remarks>
  110.        ''' Credits to: <see href="https://github.com/mrpeardotnet/WinProdKeyFinder"/>
  111.        ''' </remarks>
  112.        ''' ----------------------------------------------------------------------------------------------------
  113.        ''' <example> This is a code example.
  114.        ''' <code>
  115.        ''' Dim productKey As String = ProductKey()
  116.        ''' Console.WriteLine(productKey)
  117.        ''' </code>
  118.        ''' </example>
  119.        ''' ----------------------------------------------------------------------------------------------------
  120.        ''' <value>
  121.        ''' The Windows product key, or <see langword="Nothing"/> in case of the product key was
  122.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  123.        ''' </value>
  124.        ''' ----------------------------------------------------------------------------------------------------
  125.        Public Shared ReadOnly Property ProductKey As String
  126.            <DebuggerStepThrough>
  127.            Get
  128.                Return Licensing.GetWindowsProductKey()
  129.            End Get
  130.        End Property
  131.  
  132. #End Region
  133.  
  134. #Region " Public Methods "
  135.  
  136.        ''' ----------------------------------------------------------------------------------------------------
  137.        ''' <summary>
  138.        ''' Installs a Windows license on the current operating system.
  139.        ''' </summary>
  140.        ''' ----------------------------------------------------------------------------------------------------
  141.        ''' <remarks>
  142.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534589(v=vs.85).aspx"/>
  143.        ''' </remarks>
  144.        ''' ----------------------------------------------------------------------------------------------------
  145.        ''' <example> This is a code example.
  146.        ''' <code>
  147.        ''' Dim licFilepath As String = "C:\License.lic"
  148.        ''' InstallLicense(licFilepath)
  149.        ''' </code>
  150.        ''' </example>
  151.        ''' ----------------------------------------------------------------------------------------------------
  152.        ''' <param name="licFilepath">
  153.        ''' The license file path.
  154.        ''' </param>
  155.        ''' ----------------------------------------------------------------------------------------------------
  156.        <DebuggerStepThrough>
  157.        Public Shared Sub InstallLicense(ByVal licFilepath As String)
  158.  
  159.            Licensing.InstallLicense(New FileInfo(licFilepath))
  160.  
  161.        End Sub
  162.  
  163.        ''' ----------------------------------------------------------------------------------------------------
  164.        ''' <summary>
  165.        ''' Installs a Windows license on the current operating system.
  166.        ''' </summary>
  167.        ''' ----------------------------------------------------------------------------------------------------
  168.        ''' <remarks>
  169.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534589(v=vs.85).aspx"/>
  170.        ''' </remarks>
  171.        ''' ----------------------------------------------------------------------------------------------------
  172.        ''' <example> This is a code example.
  173.        ''' <code>
  174.        ''' Dim licFile As New FileInfo("C:\License.lic")
  175.        ''' InstallLicense(licFile)
  176.        ''' </code>
  177.        ''' </example>
  178.        ''' ----------------------------------------------------------------------------------------------------
  179.        ''' <param name="licFile">
  180.        ''' The license file.
  181.        ''' </param>
  182.        ''' ----------------------------------------------------------------------------------------------------
  183.        ''' <exception cref="PlatformNotSupportedException">
  184.        ''' Windows 7 or newer is required to use this feature.
  185.        ''' </exception>
  186.        '''
  187.        ''' <exception cref="FileNotFoundException">
  188.        ''' License file not found.
  189.        ''' </exception>
  190.        '''
  191.        ''' <exception cref="Exception">
  192.        ''' The Software Licensing Service determined that the license is invalid.
  193.        ''' or
  194.        ''' Unknown error occurred during the license installation attempt.
  195.        ''' </exception>
  196.        ''' ----------------------------------------------------------------------------------------------------
  197.        <DebuggerStepThrough>
  198.        Public Shared Sub InstallLicense(ByVal licFile As FileInfo)
  199.  
  200.            If Not (IsWin7OrGreater) Then
  201.               Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.")
  202.            End If
  203.  
  204.            If Not licFile.Exists Then
  205.                Throw New FileNotFoundException("License file not found.", licFile.FullName)
  206.            End If
  207.  
  208.            Dim licData As String = File.ReadAllText(licFile.FullName)
  209.  
  210.            Using query As New ManagementObjectSearcher("SELECT Version FROM SoftwareLicensingService")
  211.  
  212.                For Each product As ManagementObject In query.Get()
  213.  
  214.                    Dim result As UInteger
  215.                    Try
  216.                        result = CUInt(product.InvokeMethod("InstallLicense", {licData}))
  217.  
  218.                    Catch ex As COMException When (ex.HResult = -1073418209)
  219.                        Throw New Exception("The Software Licensing Service determined that the license is invalid.", ex)
  220.  
  221.                    Catch ex As COMException
  222.                        Marshal.ThrowExceptionForHR(ex.HResult)
  223.  
  224.                    Catch ex As Exception
  225.                        Throw
  226.  
  227.                    End Try
  228.  
  229.                    If (result <> 0UI) Then
  230.                        Throw New Exception("Unknown error occurred during the license installation attempt.")
  231.                    End If
  232.  
  233.                Next product
  234.  
  235.            End Using
  236.  
  237.        End Sub
  238.  
  239.        ''' ----------------------------------------------------------------------------------------------------
  240.        ''' <summary>
  241.        ''' Installs a Windows product key on the current operating system.
  242.        ''' </summary>
  243.        ''' ----------------------------------------------------------------------------------------------------
  244.        ''' <remarks>
  245.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534590(v=vs.85).aspx"/>
  246.        ''' </remarks>
  247.        ''' ----------------------------------------------------------------------------------------------------
  248.        ''' <example> This is a code example.
  249.        ''' <code>
  250.        ''' Dim productKey As String = "YTMG3-N6DKC-DKB77-7M9GH-8HVX7"
  251.        ''' InstallProductKey(productKey)
  252.        ''' </code>
  253.        ''' </example>
  254.        ''' ----------------------------------------------------------------------------------------------------
  255.        ''' <param name="productKey">
  256.        ''' The product key.
  257.        ''' </param>
  258.        ''' ----------------------------------------------------------------------------------------------------
  259.        ''' <exception cref="PlatformNotSupportedException">
  260.        ''' Windows 7 or newer is required to use this feature.
  261.        ''' </exception>
  262.        '''
  263.        ''' <exception cref="ArgumentNullException">
  264.        ''' productKey
  265.        ''' </exception>
  266.        '''
  267.        ''' <exception cref="Exception">
  268.        ''' The Software Licensing Service determined that the product key is invalid.
  269.        ''' or
  270.        ''' Unknown error occurred during the product key installation attempt.
  271.        ''' </exception>
  272.        ''' ----------------------------------------------------------------------------------------------------
  273.        <DebuggerStepThrough>
  274.        Public Shared Sub InstallProductKey(ByVal productKey As String)
  275.  
  276.            If Not (IsWin7OrGreater) Then
  277.               Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.")
  278.            End If
  279.  
  280.            If String.IsNullOrWhiteSpace(productKey) Then
  281.                Throw New ArgumentNullException("productKey")
  282.            End If
  283.  
  284.            Using query As New ManagementObjectSearcher("SELECT Version FROM SoftwareLicensingService")
  285.  
  286.                For Each product As ManagementObject In query.Get()
  287.  
  288.                    Dim result As UInteger
  289.                    Try
  290.                        result = CUInt(product.InvokeMethod("InstallProductKey", {productKey}))
  291.                        ' Installing a product key could change Windows licensing state.
  292.                        ' Since the service determines if it can shut down and when is the next start time
  293.                        ' based on the licensing state we should reconsume the licenses here.
  294.                        product.InvokeMethod("RefreshLicenseStatus", Nothing)
  295.  
  296.                    Catch ex As COMException When (ex.HResult = -1073418160)
  297.                        Throw New Exception("The Software Licensing Service determined that the product key is invalid.", ex)
  298.  
  299.                    Catch ex As COMException
  300.                        Marshal.ThrowExceptionForHR(ex.HResult)
  301.  
  302.                    Catch ex As Exception
  303.                        Throw
  304.  
  305.                    End Try
  306.  
  307.                    If (result <> 0UI) Then
  308.                        Throw New Exception("Unknown error occurred during the product key installation attempt.")
  309.                    End If
  310.  
  311.                Next product
  312.  
  313.            End Using
  314.  
  315.        End Sub
  316.  
  317.        ''' ----------------------------------------------------------------------------------------------------
  318.        ''' <summary>
  319.        ''' Uninstall the Windows product key of the current operating system.
  320.        ''' </summary>
  321.        ''' ----------------------------------------------------------------------------------------------------
  322.        ''' <remarks>
  323.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534599(v=vs.85).aspx"/>
  324.        ''' </remarks>
  325.        ''' ----------------------------------------------------------------------------------------------------
  326.        ''' <exception cref="PlatformNotSupportedException">
  327.        ''' Windows 7 or newer is required to use this feature.
  328.        ''' </exception>
  329.        '''
  330.        ''' <exception cref="Exception">
  331.        ''' Unknown error occurred during the product key uninstallation attempt.
  332.        ''' </exception>
  333.        ''' ----------------------------------------------------------------------------------------------------
  334.        <DebuggerStepThrough>
  335.        Public Shared Sub UninstallProductKey()
  336.  
  337.            If Not (IsWin7OrGreater) Then
  338.               Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.")
  339.            End If
  340.  
  341.            Using query As New ManagementObjectSearcher("SELECT Version FROM SoftwareLicensingProduct")
  342.  
  343.                For Each product As ManagementObject In query.Get()
  344.  
  345.                    Dim result As UInteger
  346.                    Try
  347.                        result = CUInt(product.InvokeMethod("UninstallProductKey", Nothing))
  348.                        ' Uninstalling a product key could change Windows licensing state.
  349.                        ' Since the service determines if it can shut down and when is the next start time
  350.                        ' based on the licensing state we should reconsume the licenses here.
  351.                        product.InvokeMethod("RefreshLicenseStatus", Nothing)
  352.  
  353.                    Catch ex As COMException
  354.                        Marshal.ThrowExceptionForHR(ex.HResult)
  355.  
  356.                    Catch ex As Exception
  357.                        Throw
  358.  
  359.                    End Try
  360.  
  361.                    If (result <> 0UI) Then
  362.                        Throw New Exception("Unknown error occurred during the product key removal attempt.")
  363.                    End If
  364.  
  365.                Next product
  366.  
  367.            End Using
  368.  
  369.        End Sub
  370.  
  371.        ''' ----------------------------------------------------------------------------------------------------
  372.        ''' <summary>
  373.        ''' Removes the Windows product key from registry (to prevent unauthorized diffusion)
  374.        ''' of the current operating system.
  375.        ''' <para></para>
  376.        ''' It does not uninstall the product key.
  377.        ''' </summary>
  378.        ''' ----------------------------------------------------------------------------------------------------
  379.        ''' <remarks>
  380.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534586(v=vs.85).aspx"/>
  381.        ''' </remarks>
  382.        ''' ----------------------------------------------------------------------------------------------------
  383.        ''' <exception cref="PlatformNotSupportedException">
  384.        ''' Windows 7 or newer is required to use this feature.
  385.        ''' </exception>
  386.        '''
  387.        ''' <exception cref="Exception">
  388.        ''' Unknown error occurred during the product key removal attempt.
  389.        ''' </exception>
  390.        ''' ----------------------------------------------------------------------------------------------------
  391.        <DebuggerStepThrough>
  392.        Public Shared Sub RemoveProductKeyFromRegistry()
  393.  
  394.            If Not (IsWin7OrGreater) Then
  395.               Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.")
  396.            End If
  397.  
  398.            Using query As New ManagementObjectSearcher("SELECT Version FROM SoftwareLicensingService")
  399.  
  400.                For Each product As ManagementObject In query.Get()
  401.  
  402.                    Dim result As UInteger
  403.                    Try
  404.                        result = CUInt(product.InvokeMethod("ClearProductKeyFromRegistry", Nothing))
  405.  
  406.                    Catch ex As COMException
  407.                        Marshal.ThrowExceptionForHR(ex.HResult)
  408.  
  409.                    Catch ex As Exception
  410.                        Throw
  411.  
  412.                    End Try
  413.  
  414.                    If (result <> 0UI) Then
  415.                        Throw New Exception("Unknown error occurred during the product key removal attempt.")
  416.                    End If
  417.  
  418.                Next product
  419.  
  420.            End Using
  421.  
  422.        End Sub
  423.  
  424.        ''' ----------------------------------------------------------------------------------------------------
  425.        ''' <summary>
  426.        ''' Updates the licensing status of the machine so that applications have access to current licensing information.
  427.        ''' </summary>
  428.        ''' ----------------------------------------------------------------------------------------------------
  429.        ''' <remarks>
  430.        ''' <see href="https://msdn.microsoft.com/en-us/library/cc534592(v=vs.85).aspx"/>
  431.        ''' </remarks>
  432.        ''' ----------------------------------------------------------------------------------------------------
  433.        ''' <exception cref="PlatformNotSupportedException">
  434.        ''' Windows 7 or newer is required to use this feature.
  435.        ''' </exception>
  436.        ''' ----------------------------------------------------------------------------------------------------
  437.        <DebuggerStepThrough>
  438.        Public Shared Sub RefreshLicenseStatus()
  439.  
  440.            If Not (IsWin7OrGreater) Then
  441.               Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.")
  442.            End If
  443.  
  444.            Using query As New ManagementObjectSearcher("SELECT Version FROM SoftwareLicensingService")
  445.  
  446.                For Each product As ManagementObject In query.Get()
  447.                    product.InvokeMethod("RefreshLicenseStatus", Nothing)
  448.                Next product
  449.  
  450.            End Using
  451.  
  452.        End Sub
  453.  
  454. #End Region
  455.  
  456. #Region " Private Members "
  457.  
  458.        ''' ----------------------------------------------------------------------------------------------------
  459.        ''' <summary>
  460.        ''' Gets a value that determines whether the current operating system is <c>Windows 7</c>, or greater.
  461.        ''' </summary>
  462.        ''' ----------------------------------------------------------------------------------------------------
  463.        ''' <example> This is a code example.
  464.        ''' <code>
  465.        ''' If Not IsWin7OrGreater Then
  466.        '''     Throw New PlatformNotSupportedException("This application cannot run under the current Windows version.")
  467.        ''' End If
  468.        ''' </code>
  469.        ''' </example>
  470.        ''' ----------------------------------------------------------------------------------------------------
  471.        ''' <value>
  472.        ''' A value that determines whether the current operating system is <c>Windows 7</c>, or greater.
  473.        ''' </value>
  474.        ''' ----------------------------------------------------------------------------------------------------
  475.        Private Shared ReadOnly Property IsWin7OrGreater() As Boolean
  476.            <DebuggerStepThrough>
  477.            Get
  478.                Return (Environment.OSVersion.Platform = PlatformID.Win32NT) AndAlso
  479.                       (Environment.OSVersion.Version.CompareTo(New Version(6, 1)) >= 0)
  480.            End Get
  481.        End Property
  482.  
  483.        ''' ----------------------------------------------------------------------------------------------------
  484.        ''' <summary>
  485.        ''' Gets a value that determines whether the current operating system is <c>Windows 8</c>, or greater.
  486.        ''' </summary>
  487.        ''' ----------------------------------------------------------------------------------------------------
  488.        ''' <example> This is a code example.
  489.        ''' <code>
  490.        ''' If Not IsWin8OrGreater Then
  491.        '''     Throw New PlatformNotSupportedException("This application cannot run under the current Windows version.")
  492.        ''' End If
  493.        ''' </code>
  494.        ''' </example>
  495.        ''' ----------------------------------------------------------------------------------------------------
  496.        ''' <value>
  497.        ''' A value that determines whether the current operating system is <c>Windows 8</c>, or greater.
  498.        ''' </value>
  499.        ''' ----------------------------------------------------------------------------------------------------
  500.        Private Shared ReadOnly Property IsWin8OrGreater() As Boolean
  501.            <DebuggerStepThrough>
  502.            Get
  503.                Return (Environment.OSVersion.Platform = PlatformID.Win32NT) AndAlso
  504.                       (Environment.OSVersion.Version.CompareTo(New Version(6, 2)) >= 0)
  505.            End Get
  506.        End Property
  507.  
  508.        ''' ----------------------------------------------------------------------------------------------------
  509.        ''' <summary>
  510.        ''' Gets the Windows product key.
  511.        ''' <para></para>
  512.        ''' Note that the return value could be <see langword="Nothing"/> in case of the product key was
  513.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  514.        ''' </summary>
  515.        ''' ----------------------------------------------------------------------------------------------------
  516.        ''' <remarks>
  517.        ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa394239(v=vs.85).aspx"/>
  518.        ''' </remarks>
  519.        ''' ----------------------------------------------------------------------------------------------------
  520.        ''' <returns>
  521.        ''' The Windows product key, or <see langword="Nothing"/> in case of the product key was
  522.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  523.        ''' </returns>
  524.        ''' ----------------------------------------------------------------------------------------------------
  525.        <DebuggerStepperBoundary>
  526.        Private Shared Function GetWindowsProductId() As String
  527.  
  528.            Dim result As String = Nothing
  529.  
  530.            Using query As New ManagementObjectSearcher("SELECT SerialNumber FROM Win32_OperatingSystem")
  531.  
  532.                For Each product As ManagementObject In query.Get()
  533.                    result = CStr(product.Properties("SerialNumber").Value)
  534.                Next product
  535.  
  536.            End Using
  537.  
  538.            Return result
  539.  
  540.        End Function
  541.  
  542.        ''' ----------------------------------------------------------------------------------------------------
  543.        ''' <summary>
  544.        ''' Gets the Windows product key.
  545.        ''' <para></para>
  546.        ''' Note that the return value could be <see langword="Nothing"/> in case of the product key was
  547.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  548.        ''' </summary>
  549.        ''' ----------------------------------------------------------------------------------------------------
  550.        ''' <remarks>
  551.        ''' Credits to: <see href="https://github.com/mrpeardotnet/WinProdKeyFinder"/>
  552.        ''' </remarks>
  553.        ''' ----------------------------------------------------------------------------------------------------
  554.        ''' <returns>
  555.        ''' The Windows product key, or <see langword="Nothing"/> in case of the product key was
  556.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  557.        ''' </returns>
  558.        ''' ----------------------------------------------------------------------------------------------------
  559.        <DebuggerStepperBoundary>
  560.        Private Shared Function GetWindowsProductKey() As String
  561.  
  562.            Dim regKey As RegistryKey
  563.            Dim regValue As Byte()
  564.            Dim productKey As String
  565.  
  566.            If Environment.Is64BitOperatingSystem Then
  567.                regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)
  568.            Else
  569.                regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
  570.            End If
  571.  
  572.            Using regKey
  573.                regValue = DirectCast(regKey.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").
  574.                                             GetValue("DigitalProductId", New Byte() {}, RegistryValueOptions.None),
  575.                                             Byte())
  576.            End Using
  577.  
  578.            productKey = Licensing.DecodeProductKey(regValue)
  579.            Return productKey
  580.  
  581.        End Function
  582.  
  583.        ''' ----------------------------------------------------------------------------------------------------
  584.        ''' <summary>
  585.        ''' Decode and return the Windows Product Key that is encoded in the specified Windows Product Identifier.
  586.        ''' </summary>
  587.        ''' ----------------------------------------------------------------------------------------------------
  588.        ''' <remarks>
  589.        ''' Credits to: <see href="https://github.com/mrpeardotnet/WinProdKeyFinder"/>
  590.        ''' </remarks>
  591.        ''' ----------------------------------------------------------------------------------------------------
  592.        ''' <returns>
  593.        ''' The Windows product key, or <see langword="Nothing"/> in case of the product key was
  594.        ''' completely removed from the Windows Registry (eg. using tools like <c>slmgr.vbs /cpky</c>).
  595.        ''' </returns>
  596.        ''' ----------------------------------------------------------------------------------------------------
  597.        <DebuggerStepperBoundary>
  598.        Private Shared Function DecodeProductKey(ByVal windowsProductId As Byte()) As String
  599.  
  600.            If (IsWin8OrGreater) Then ' Decode key from Windows 8 to Windows 10
  601.  
  602.                Dim key As String = String.Empty
  603.                Dim keyOffset As Integer = 52
  604.                Dim isWin8 As Byte = CByte((windowsProductId(66) \ 6) And 1)
  605.                windowsProductId(66) = CByte((windowsProductId(66) And &HF7) Or (isWin8 And 2) * 4)
  606.                Dim digits As String = "BCDFGHJKMPQRTVWXY2346789"
  607.                Dim last As Integer = 0
  608.  
  609.                For i As Integer = 24 To 0 Step -1
  610.                    Dim current As Integer = 0
  611.                    For j As Integer = 14 To 0 Step -1
  612.                        current = current * 256
  613.                        current = windowsProductId(j + keyOffset) + current
  614.                        windowsProductId(j + keyOffset) = CByte(current \ 24)
  615.                        current = current Mod 24
  616.                        last = current
  617.                    Next
  618.                    key = digits(current) + key
  619.                Next
  620.                If (key = "BBBBBBBBBBBBBBBBBBBBBBBBB") Then
  621.                    Return Nothing
  622.                End If
  623.  
  624.                Dim keypart1 As String = key.Substring(1, last)
  625.                Dim keypart2 As String = key.Substring(last + 1, key.Length - (last + 1))
  626.                key = keypart1 & "N" & keypart2
  627.  
  628.                For i As Integer = 5 To (key.Length - 1) Step 6
  629.                    key = key.Insert(i, "-")
  630.                Next i
  631.  
  632.                Return key
  633.  
  634.            Else ' Decode key from Windows XP to Windows 7
  635.                Dim keyStartIndex As Integer = 52
  636.                Dim keyEndIndex As Integer = keyStartIndex + 15
  637.                Dim decodeLength As Integer = 29
  638.                Dim decodeStringLength As Integer = 15
  639.                Dim decodedChars As Char() = New Char(decodeLength - 1) {}
  640.                Dim hexPid As New ArrayList()
  641.                Dim digits As Char() = {
  642.                        "B"c, "C"c, "D"c, "F"c, "G"c, "H"c,
  643.                        "J"c, "K"c, "M"c, "P"c, "Q"c, "R"c,
  644.                        "T"c, "V"c, "W"c, "X"c, "Y"c, "2"c,
  645.                        "3"c, "4"c, "6"c, "7"c, "8"c, "9"c
  646.                }
  647.  
  648.                For i As Integer = keyStartIndex To keyEndIndex
  649.                    hexPid.Add(windowsProductId(i))
  650.                Next i
  651.  
  652.                For i As Integer = (decodeLength - 1) To 0 Step -1
  653.                    ' Every sixth char is a separator.
  654.                    If (i + 1) Mod 6 = 0 Then
  655.                        decodedChars(i) = "-"c
  656.  
  657.                    Else
  658.                        ' Do the actual decoding.
  659.                        Dim digitMapIndex As Integer = 0
  660.                        For j As Integer = (decodeStringLength - 1) To 0 Step -1
  661.                            Dim byteValue As Integer = (digitMapIndex << 8) Or CByte(hexPid(j))
  662.                            hexPid(j) = CByte(byteValue \ 24)
  663.                            digitMapIndex = byteValue Mod 24
  664.                            decodedChars(i) = digits(digitMapIndex)
  665.                        Next
  666.  
  667.                    End If
  668.  
  669.                Next i
  670.  
  671.                Return New String(decodedChars)
  672.  
  673.            End If
  674.  
  675.        End Function
  676.  
  677. #End Region
  678.  
  679.    End Class
  680.  
  681. ' End Namespace
  682.  
  683. #End Region
  684.  
« Última modificación: 1 Junio 2017, 18:17 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #509 en: 3 Junio 2017, 03:55 am »

¿Cómo bloquear la ejecución del administrador de tareas de Windows?

Este código lo he desarrollado para darle solución al siguiente problema: bloquear la ejecución del administrador de tareas de Windows (taskmgr.exe)

Además de eso, el código también bloquea la ejecución del hijack/sustituto del admiinstrador de tareas... suponiendo que el usuario haya definido tal hijack en el registro de Windows, claro está.

La metodología que he usado es la más sencilla (y por ende también la más eludible): abrir el stream del archivo para mantenerlo en uso y prohibir la compartición del archivo.
De esta manera, y mientras tengamos abierto el stream en nuestra aplicación, evitaremos una ejecución a demanda del administrador de tareas, incluyendo el intento de ejecución desde el diálogo de Logon de Windows.

Por supuesto el efecto no es permanente, tan solo perdurará hasta que nuestra aplicación finalice su ejecución o hasta que por el motivo que sea decidamos liberar el stream manualmente.

He usado esta metodología basicamente por que la intención de esto no es el desarrollo de malware (y para ser sincero no he querido complicarme más la vida puesto que el diseño de Malware y la ing. inversa no es mi fuerte), sino una simple utilidad a la que darle un uso ético, como por ejemplo podría ser poner impedimentos para intentar evitar que el usuario pueda matar nuestro proceso mientras estamos realizando una operación crítica e irreversible que podria dañar el sistema operativo si se detiene de forma anómala.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Prevents any attempt for the current user from reading and running the 'taskmgr.exe' file
  4. ''' and any defined hijack in the system (if any)
  5. ''' <para></para>
  6. ''' Note that the file blocking is not permanent.
  7. ''' <para></para>
  8. ''' This function will return a <see cref="FileStream"/> Array that contains the 'taskmgr.exe' file stream(s)
  9. ''' opened with <see cref="FileAccess.Read"/> access and <see cref="FileShare.None"/> sharing.
  10. ''' <para></para>
  11. ''' So in order to unblock the access to the file(s), just dispose the opened stream(s) or terminate the calling aplication.
  12. ''' </summary>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <returns>
  15. ''' A <see cref="FileStream"/> Array that contains the 'taskmgr.exe' file stream(s)
  16. ''' opened with <see cref="FileAccess.Read"/> access and <see cref="FileShare.None"/> sharing.
  17. ''' </returns>
  18. ''' ----------------------------------------------------------------------------------------------------
  19. Public Shared Function BlockWindowsTaskManager() As FileStream()
  20.  
  21.    ' Build a list with the legit tskmgr.exe file(s).
  22.    Dim tkmgrFiles As New List(Of FileInfo) From { ' C:\Windows\System32\taskmgr.exe
  23.        New FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "taskmgr.exe"))
  24.    }
  25.    If (Environment.Is64BitOperatingSystem) AndAlso (Environment.Is64BitProcess) Then ' C:\Windows\SysWOW64\taskmgr.exe
  26.        tkmgrFiles.Add(New FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "taskmgr.exe")))
  27.    End If
  28.  
  29.    ' Add to the list the taskmgr.exe hijacked file, if any.
  30.    Dim hijackValue As String = GetTaskManagerHijack()
  31.    If Not String.IsNullOrWhiteSpace(hijackValue) Then
  32.        tkmgrFiles.Add(New FileInfo(hijackValue))
  33.    End If
  34.  
  35.    ' Build a list where to add the open file streams.
  36.    Dim tkmgrStreams As New List(Of FileStream)
  37.  
  38.    tkmgrFiles.ForEach(
  39.        Sub(ByVal file As FileInfo)
  40.            ' Ensure that any instance of the taskmgr processes are running; otherwise, we must terminate them.
  41.            Dim processName As String = Path.GetFileNameWithoutExtension(file.Name)
  42.            For Each p As Process In Process.GetProcessesByName(processName)
  43.                Using p
  44.                    Try
  45.                        If Not (p.HasExited) Then
  46.                            p.Kill()
  47.                            ' Wait a reasonable time interval if stuck/hanged process.
  48.                            p.WaitForExit(CInt(TimeSpan.FromSeconds(10).TotalMilliseconds))
  49.                        End If
  50.                    Catch ex As Exception ' Failed to terminate the process
  51.                        ' Since we can still block an open file (if it was open with read sharing) but
  52.                        ' we can't terminate the current running/unblocked instance,
  53.                        ' so we conclude the overall operation failed and rollback previous blocks then finish here.
  54.                        tkmgrStreams.ForEach(Sub(sr As Stream) sr.Dispose())
  55.                        Throw
  56.                    End Try
  57.                End Using ' p
  58.            Next p
  59.  
  60.            If (file.Exists()) Then
  61.                Dim fs As FileStream
  62.                Try
  63.                    fs = file.Open(FileMode.Open, FileAccess.Read, FileShare.None)
  64.                    tkmgrStreams.Add(fs)
  65.  
  66.                    ' Catch ex As IOException When (ex.HResult = -2147024864) ' File its being used by this or another process.
  67.                    ' This exception can occur if calling this function twice without disposing the returned stream(s) before the second call.
  68.  
  69.                Catch ex As Exception ' File can't be opened for whatever reason.
  70.                    ' Since we can't open/block all the required files,
  71.                    ' we conclude the overall operation failed and rollback previous blocks then finish here.
  72.                    tkmgrStreams.ForEach(Sub(sr As Stream) sr.Dispose())
  73.                    Throw
  74.  
  75.                End Try
  76.            End If
  77.  
  78.        End Sub)
  79.  
  80.    Return tkmgrStreams.ToArray()
  81.  
  82. End Function

+

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Determines whether the legit 'taskmgr.exe' file has a hijack defined in the Windows registry,
  4. ''' then returns the registry value that points to the hijack file path.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <returns>
  8. ''' The resulting hijack registry value,
  9. ''' or <see langword="Nothing"/> (null) if a 'taskmgr.exe' hijack doesn't exist.
  10. ''' </returns>
  11. ''' ----------------------------------------------------------------------------------------------------
  12. Public Shared Function GetTaskManagerHijack() As String
  13.  
  14.    Dim hijackSubkey As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe"
  15.  
  16.    Using regKey As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)
  17.  
  18.        Return DirectCast(regKey.OpenSubKey(hijackSubkey, RegistryRights.ReadKey)?.
  19.                                 GetValue("Debugger", Nothing, RegistryValueOptions.None), String)
  20.  
  21.    End Using
  22.  
  23. End Function

Ejemplo de uso:
Código
  1. Dim tskmgrFiles As FileStream() = BlockWindowsTaskManager()
  2. For Each fs As FileStream In tskmgrFiles
  3.    Debug.WriteLine(fs.Name)
  4.    ' fs.Close() ' Call this to unblock file access.
  5. Next fs

Resultado de ejecución en mi equipo de 64-Bits con Windows 10 instalado donde tengo asignado un hijack para correr el administrador de tareas de Windows 7 en lugar del de Windows 10:
Cita de: Visual Studio Debug Output Window
C:\Windows\system32\taskmgr.exe
C:\Windows\SysWOW64\taskmgr.exe
C:\Windows\system32\taskmgr7.exe

Hasta donde yo he probado, funciona.

Nótese que para optimizar los resultados el executable que llame a la función BlockWindowsTaskManager() debe ser de la misma arquitectura que el sistema operativo donde éste sea ejecutado, pues si Windows es de 64-Bit y nuestro executable es de 32, entonces Windows automáticamente hará redirección WOW64, o dicho de otra forma si estamos en Win64 y llamamos a la función BlockWindowsTaskManager() desde un WinExe32 entonces tan solo podremos bloquear 1 taskmgr.exe de los 2 taskmgr.exe legítimos en Windows x64. Y lo mismo sucederá con el hijack puesto que un executable de 32 bits no puede acceder al visor de registro de 64 bits.

Saludos!
« Última modificación: 3 Junio 2017, 04:24 am por Eleкtro » En línea



Páginas: 1 ... 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [51] 52 53 54 55 56 57 58 59 60 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines