Menú

Mostrar Mensajes

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

Mostrar Mensajes Menú

Mensajes - Eleкtro

#3721
Otra forma de llevarlo a cabo sería utilizando el método Win32 RtlSetProcessIsCritical, el cual lo considero más apropiado o "directo" puesto que afecta al proceso actual desde el que se invocó dicho método, pero claro está, si queremos que afecte a un proceso distinto, entonces hay que usar la ya mencionada función Win32 NTSetInformationProcess.

Hay que tener en cuenta también, que para poder establecer un proceso cómo "crítico", dicho proceso necesita tener establecido el privilegio de proceso "SE_DEBUG_NAME" (y si usasemos la función NtSetInformationProcess, es necesario que el proceso sea abierto con el privilegio "PROCESS_SET_INFORMATION"), por lo que esto aumenta considerablemente el tamaño del código fuente, declarando y utilizando los P/Invokes para asegurarnos (o al menos intentarlo) que todo salga de forma esperada.

Para determinar si un proceso es crítico o no lo es, en versiones superiores a Windows XP podemos llamar a la función Win32 IsProcessCritical, la cual es muy cómoda y abstracta, pero en Windows XP deberemos utilizar la función NtQueryInformationProcess, la cual es insegura llamarla dependiendo de la versión de Windows desde la que se llame (como indica la documentación de dicha función en MSDN), y como Windows XP es un sistema operativo obsoleto, no me he molestado en implementar dicha función.

Aquí está mi solución (probado en Windows 10 y Windows XP), un "todo en uno", tanto para establecer el proceso actual como "Crítico", "Normal", y averiguar si un proceso es crítico o no lo es:

( Todos los P/Invokes del código fuente, excepto el método 'RtlSetProcessIsCritical', los he sacado de mi framework ElektroKit, lo comento por que con mi librería podeis hacer muchas virguerías al poder utilizar todos estos miembros Win32...y una infinidad más en el namespace Elektro.Interop.Win32:
)

Clase para definir el P/Invoking:
Código (vbnet) [Seleccionar]
Namespace Win32

   Friend NotInheritable Class NativeMethods

       <DebuggerNonUserCode>
       Private Sub New()
       End Sub

       <Flags>
       Friend Enum TokenPrivilegesFlags As UInteger
           PrivilegeEnabledBYDefault = &H1UI
           PrivilegeEnabled = &H2UI
           PrivilegeRemoved = &H4UI
           PrivilegeUsedForAccess = &H80000000UI
       End Enum

       <Flags>
       Friend Enum AccessRights As UInteger
           TokenAdjustPrivileges = &H32UI
           TokenQuery = &H8UI
       End Enum

       <StructLayout(LayoutKind.Sequential)>
       Friend Structure TokenPrivileges
           <MarshalAs(UnmanagedType.I4)>
           Public PrivilegeCount As Integer

           <MarshalAs(UnmanagedType.Struct)>
           Public Privileges As LuIdAndAttributes
       End Structure

       <StructLayout(LayoutKind.Sequential)>
       Friend Structure LuIdAndAttributes
           <MarshalAs(UnmanagedType.Struct)>
           Public PLuid As Luid

           <MarshalAs(UnmanagedType.U4)>
           Public Attributes As TokenPrivilegesFlags
       End Structure

       <StructLayout(LayoutKind.Sequential)>
       Friend Structure Luid
           <MarshalAs(UnmanagedType.U4)>
           Public LowPart As UInteger

           <MarshalAs(UnmanagedType.I4)>
           Public HighPart As Integer
       End Structure

       <DllImport("advapi32.dll", SetLastError:=True)>
       Friend Shared Function AdjustTokenPrivileges(
                  <MarshalAs(UnmanagedType.SysInt)> ByVal tokenHandle As IntPtr,
                    <MarshalAs(UnmanagedType.Bool)> ByVal disableAllPrivileges As Boolean,
                  <MarshalAs(UnmanagedType.Struct)> ByRef newState As TokenPrivileges,
                      <MarshalAs(UnmanagedType.U4)> ByVal bufferLength As UInteger,
                  <MarshalAs(UnmanagedType.SysInt)> ByVal previousState As IntPtr,
                  <MarshalAs(UnmanagedType.SysInt)> ByVal returnLength As IntPtr
       ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       <DllImport("advapi32.dll", SetLastError:=True)>
       Friend Shared Function OpenProcessToken(
             <MarshalAs(UnmanagedType.SysInt)> ByVal processHandle As IntPtr,
                 <MarshalAs(UnmanagedType.U4)> ByVal desiredAccess As AccessRights,
             <MarshalAs(UnmanagedType.SysInt)> ByRef tokenHandle As IntPtr
       ) As <MarshalAs(UnmanagedType.I4)> Integer
       End Function

       <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode, BestFitMapping:=False, ThrowOnUnmappableChar:=True)>
       Friend Shared Function LookupPrivilegeValue(
                 <MarshalAs(UnmanagedType.LPWStr)> ByVal lpSystemName As String,
                 <MarshalAs(UnmanagedType.LPWStr)> ByVal lpName As String,
                 <MarshalAs(UnmanagedType.Struct)> ByRef lpLuid As Luid
       ) As <MarshalAs(UnmanagedType.I4)> Integer
       End Function

       <DllImport("Kernel32.dll", SetLastError:=True)>
       Friend Shared Function IsProcessCritical(
              <MarshalAs(UnmanagedType.SysInt)> ByVal hProcess As IntPtr,
                <MarshalAs(UnmanagedType.Bool)> ByRef refIsCritical As Boolean
       ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       <DllImport("ntdll.dll", EntryPoint:="RtlSetProcessIsCritical", SetLastError:=True)>
       Friend Shared Sub SetCurrentProcessIsCritical(
                     <MarshalAs(UnmanagedType.Bool)> ByVal isCritical As Boolean,
                     <MarshalAs(UnmanagedType.Bool)> ByRef refWasCritical As Boolean,
                     <MarshalAs(UnmanagedType.Bool)> ByVal needSystemCriticalBreaks As Boolean)
       End Sub

   End Class

End Namespace


Clase para definir los métodos o abstracción de los algoritmos:
Código (vbnet) [Seleccionar]
Imports Win32
Imports Win32.NativeMethods

Namespace Tools

   Public NotInheritable Class ProcessUtil

       <DebuggerNonUserCode>
       Private Sub New()
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Specifies a critical state of a process.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Public Enum ProcessCriticalState As Integer

           ''' <summary>
           ''' Process isn't critical.
           ''' </summary>
           NonCritical = 0

           ''' <summary>
           ''' Process is critical.
           ''' </summary>
           Critical = 1

       End Enum

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Determines whether the specified process is considered <c>critical</c>.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="handle">
       ''' A handle (<see cref="IntPtr"/>) to the process to query.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <returns>
       ''' A <see cref="ProcessCriticalState"/> enumeration value indicating the critical state.
       ''' </returns>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Shared Function GetProcessCriticalState(ByVal handle As IntPtr) As ProcessCriticalState

           If (handle = IntPtr.Zero) Then
               Throw New ArgumentNullException(paramName:="handle")

           Else
               Dim result As Boolean
               Dim win32Err As Integer

               NativeMethods.IsProcessCritical(handle, result)
               win32Err = Marshal.GetLastWin32Error()

               If (win32Err <> 0) Then
                   Throw New Win32Exception(win32Err)

               Else
                   Select Case result
                       Case True
                           Return ProcessCriticalState.Critical

                       Case Else
                           Return ProcessCriticalState.NonCritical

                   End Select

               End If

           End If

       End Function

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Determines whether the caller process is considered <c>critical</c>.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <returns>
       ''' A <see cref="ProcessCriticalState"/> enumeration value indicating the critical state.
       ''' </returns>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Shared Function GetCurrentProcessCriticalState() As ProcessCriticalState

           Return ProcessUtil.GetProcessCriticalState(Process.GetCurrentProcess().Handle)

       End Function

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Sets the critical state for the caller process.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="state">
       ''' The new critical state.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="InvalidEnumArgumentException">
       ''' state
       ''' </exception>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Shared Sub SetCurrentProcessCriticalState(ByVal state As ProcessCriticalState)

           Dim isCritical As Boolean
           Dim wasCritical As Boolean
           Dim needSystemCriticalBreaks As Boolean = False

           Select Case state

               Case ProcessCriticalState.Critical
                   isCritical = True

               Case ProcessCriticalState.NonCritical
                   isCritical = False

               Case Else
                   Throw New InvalidEnumArgumentException(argumentName:="state", invalidValue:=state,
                                                      enumClass:=GetType(ProcessCriticalState))
                   Exit Sub

           End Select

           ' Set "SE_DEBUG_NAME" process privilege,
           ' required to debug and adjust the memory of a process owned by another account.
           ProcessUtil.SetCurrentProcessPrivilege("SE_DEBUG_NAME")

           ' Set the critical state.
           NativeMethods.SetCurrentProcessIsCritical(isCritical, wasCritical, needSystemCriticalBreaks)

#If DEBUG Then
           Debug.WriteLine(String.Format("Current process was critical?: {0}", wasCritical))
#End If

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Sets a process privilege for the caller process.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <remarks>
       ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716%28v=vs.85%29.aspx"/>
       ''' </remarks>
       ''' ----------------------------------------------------------------------------------------------------
       Private Shared Sub SetCurrentProcessPrivilege(ByVal privilegeName As String)

           Dim hToken As IntPtr
           Dim tkp As New TokenPrivileges

           NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle,
                                          AccessRights.TokenAdjustPrivileges Or
                                          AccessRights.TokenQuery,
                                          hToken)

           With tkp
               .PrivilegeCount = 1
               .Privileges.Attributes = TokenPrivilegesFlags.PrivilegeEnabled
           End With

           NativeMethods.LookupPrivilegeValue(Nothing, privilegeName, tkp.Privileges.PLuid)
           NativeMethods.AdjustTokenPrivileges(hToken, False, tkp, 0UI, IntPtr.Zero, IntPtr.Zero)

       End Sub

   End Class

End Namespace


Clase (cualquiera) donde utilizar los miembros definidos:
Código (vbnet) [Seleccionar]
Imports Tools
Imports Tools.ProcessUtil

Public NotInheritable Class Form1 : Inherits Form

   ' Establecer el estado del proceso actual a: crítico.
   Private Sub Button1_Click() Handles Button1.Click
       ProcessUtil.SetCurrentProcessCriticalState(ProcessCriticalState.Critical)
   End Sub

   ' Establecer el estado del proceso actual a: no-crítico.
   Private Sub Button2_Click() Handles Button2.Click
       ProcessUtil.SetCurrentProcessCriticalState(ProcessCriticalState.NonCritical)
   End Sub

   ' Determinar el estado del proceso actual.
   Private Sub Button3_Click() Handles Button3.Click
       Dim state As ProcessCriticalState = ProcessUtil.GetCurrentProcessCriticalState()
       MessageBox.Show(String.Format("Is process critical?: {0}", CBool(state)))
   End Sub

End Class
#3722
Simplemente haz un ordenamiento basado en el índice de elementos obtenidos partiendo cada elemento por el caracter delimitador ";", una forma de aplicar de manera simplificada lo que acabo de mencionar sería usando LINQ:

Código (vbnet) [Seleccionar]
Dim items As String() = {
   "052;Juan;Lopez;México",
   "101;Enrique;Morales;Guatemala",
   "005;John;McCain;USA",
   "034;María;Delgado;España"
}

Dim sorted As IEnumerable(Of String) =
   From item As String In items
   Order By item.Split(";"c)(0)

For Each item As String In sorted
   Console.WriteLine(item)
Next





Pero, la solución más apropiada sería que no uses un Array, sino una colección de un tipo personalizado donde encapsular la información de manera "individual" u organizada, como por ejemplo...:

Código (vbnet) [Seleccionar]
<Serializable>
Public NotInheritable Class Person

   Public ReadOnly Property Index As String
   Public ReadOnly Property Name As String
   Public ReadOnly Property Surname As String
   Public ReadOnly Property Country As String

   <DebuggerNonUserCode>
   Private Sub New()
   End Sub

   <DebuggerStepThrough>
   Public Sub New(ByVal index As String,
                  ByVal name As String,
                  ByVal surname As String,
                  ByVal country As String)

       Me.Index = index
       Me.Name = name
       Me.Surname = surname
       Me.Country = country

   End Sub

End Class


Código (vbnet) [Seleccionar]
Dim persons As New List(Of Person)
persons.Add(New Person("052", "Juan", "Lopez", "México"))
...


Y entonces, para ordenar ascendentemente puedes specificar la propiedad que desees:
Código (vbnet) [Seleccionar]
Dim sorted As List(Of Person) =
   persons.OrderBy(Function(p As Person) p.Country).ToList()


Saludos.
#3723
Cita de: TrashAmbishion en 14 Abril 2016, 05:34 AMestoy haciendo lo siguiente añado la referencia

Declaro una variable
Código (vbnet) [Seleccionar]
Dim prueba As Elektro.Net.Tools.NetworkUtil

prueba me sale sin ningun metodo ni propiedad... que puede estar pasando toy con vs2015

Hola

No sale ningún miembro por que no le has asignado ningún valor a dicha variable (es una referecia nula), pero de todas formas la clase Elektro.Net.Tools.NetworkUtil no es instanciable, por lo que no le encuentro sentido a lo que estás intentando, ¿Cual es tu intención con esa variable?.

Si lo que pretendes es crear una referencia corta del espacio de nombres, entonces puedes hacerlo de la siguiente manera:
Código (vbnet) [Seleccionar]
Imports prueba = Elektro.Net.Tools.NetworkUtil

Public NotInheritable Class Form1 : Inherits Form

   Private Sub Test() Handles MyBase.Load

       Dim ip As String = prueba.GetPublicIp()
       Console.WriteLine(ip)

   End Sub

End Class


PD: Las clases que son instanciables están en los nombres de espacios que empiezan por: Elektro.X.Types (en este caso Elektro.Net.Types), y las que no son instanciables están en los espacios de nombre que empiezan por: Elektro.X.Tools (en este caso Elektro.Net.Tools).

Espero que te sirva de ayuda!

Saludos
#3724
Cita de: 01munrra en  8 Abril 2016, 06:20 AMque puedo hacer para que lo compare como si fueran 2 numeros.?? :huh:

La comparación de texto se compara caracter por caracter, y da los mismos resultados que se pueden ver en el ordenamiento lexicográfico, ya que "9" es mayor que "1", por ende "90" es mayor que "100".




Asumiendo que los valores introducidos siempre serán números dentro del rango aceptable para un valor de tipo Int32, entonces la manera más rápida en términos de rendimiento sería realizando un casteo (en la expresión a evaluar):

Código (vbnet) [Seleccionar]
TextBox1.Text = CStr(90)
TextBox2.Text = CStr(100)

If (CInt(TextBox1.Text) <= CInt(TextBox2.Text)) Then
   ' ...

Else
   ' ...

End If


De lo contrario, es decir, si los datos introducidos son inseguros, entonces puedes aplicar un control de errores básico para comprobar si los valores de texto se pueden convertir a enteros:
Código (vbnet) [Seleccionar]
TextBox1.Text = CStr(1)
TextBox2.Text = "qwerty"

Dim valueA As Integer
Dim valueB As Integer

If Not (Integer.TryParse(TextBox1.Text, valueA)) OrElse
  Not (Integer.TryParse(TextBox2.Text, valueB)) Then
   MessageBox.Show("Error")

Else
   '...

End If


Dicho esto, ten en cuenta que no es necesario utilizar la función Trim, las funciones de conversión a enteros ya se encargan de la lógica respecto al tratamiento de los espacios en blanco a la izquierda y derecha, utilizando Trim solo consigues hacer más pesado tu algoritmo, aunque realmente es algo que no tiene ninguna importancia cuando queremos comparar eventualmente 2 valores, pero mejor acostumbrarse a intentar ser lo más eficiente posible hasta cuando no sea necesario, ya que sabiendo estas cosas al menos ayudarán para cuando necesites aplicar un rendimiento elevado en comparaciones más intensivas o costosas.

De todas formas, en caso de que quieras usar Trim por el motivo que sea, en este u otros códigos me refiero, entonces deberías usar la extensión de método String.Trim();
actualmente estás utilizando la función Trim del espacio de nombres Microsoft.VisualBasic, el cual todo su contenido o miembros son una porquería deprecada en términos de rendimiento (a pesar de ser puro código .Net), intenta evitar usar nada como Left, Mid, y etc, puesto que tienes un equivalente altamente cualificado (para cualquier metodo de VB6) en el resto de la librería de classes de .Net Framework.

Saludos
#3725
Cita de: luis456 en  7 Abril 2016, 18:07 PM
Que si hombre lo que paso es que solo vi lo de Lekim ,tenia un ojo en el visual y otro aca no lo vi bien jeje como siempre gracias Elektro

Clausurado este post jejje hasta la siguiente pregunta  :silbar: :silbar: :silbar:


Luis

Te lo pregunto más que nada por que yo no me voy a seguir conectando con la misma frecuencia al foro por motivos...indeseables, por si necesitas (mi) ayuda AHORA. ¿seguro que se ha resuelto tu duda?, de lo contrario dilo sin miedo, que no como xd

saludos
#3726
Cita de: luis456 en  7 Abril 2016, 16:55 PMno creo que no se pueda convertir los datos de un listbox en una simple variable

Asumo que por variable te estás refiriendo a un Array de enteros, ¿has leido mi última respuesta en este hilo?, ahí te expliqué como hacerlo, y de varias maneras...

Si no es eso lo que quieres hacer entonces yo no me estoy enterando (para variar...)

Saludos
#3727
¿Para convertir una colección genérica a tabla html?, no, y desconozco el motivo, quizás pueda ser para evitar implementar funcionalidades basadas en asunciones de objetos representables en texto, pero esta ausencia de funcionalidad en la librería de clases de .NetFx nos presenta lugar a que existan cientos de soluciones home-made (que ya podrías haber buscado...) que hacen esas asunciones y puedes encontrar en Google, como por ejemplo esta:




Para crear una tabla html, desde Cero, si, puedes hacerlo.

En ASP.Net se puede utilizar el control Htmltable para crear y renderizar una tabla Html estática:


En WinForms puedes aprovechar ese control para poder crear una tabla Html en tiempo de ejecución, de forma guiada, mediante tipos/classes que representan la tabla, las filas y sus celdas.

Te muestro un ejemplo (en el enlace de arriba tienes otro ejemplo, basado en ASP.Net):

Código (vbnet) [Seleccionar]
Dim html As String

Using t As New HtmlTable,
    tr As New HtmlTableRow,
    td As New HtmlTableCell,
    sw As New StringWriter

   With t
       .BgColor = ColorTranslator.ToHtml(Color.Black)
       .Border = 2
       .BorderColor = ColorTranslator.ToHtml(Color.Gold)
       .Height = "300px"
       .Width = "200px"
   End With

   With td
       .BgColor = ColorTranslator.ToHtml(Color.DarkGray)
       .BorderColor = ColorTranslator.ToHtml(Color.LightGray)
       .Height = "10px"
       .InnerText = "Hello World!"
   End With

   tr.Cells.Add(td)
   t.Rows.Add(tr)

   t.RenderControl(New HtmlTextWriter(sw))
   html = sw.ToString()

   Console.WriteLine(html)

End Using


Resultado de ejecución:
Código (vbnet) [Seleccionar]
<table bgcolor="Black" border="2" bordercolor="Gold" height="300px" width="200px">
<tr>
<td bgcolor="DarkGray" bordercolor="LightGrey" height="10px">Hello World!</td>
</tr>
</table>


Sabiendo esto, puedes crear un método de uso genérico o extensión de método, solo tienes que iterar los elementos de "X" colección para ir construyendo la tabla html de forma automatizada, aunque en realidad también puedes hacer lo mismo que acabo de mencionar pero construyendo el string por completo con la class StringBuilder (como en la url de StackOverflow), cosa que yo no recomiendo, pues a la larga es mucho más rentable o beneficioso y llevadero el utilizar tipos que representan lo que quieres llevar a cabo (HtmlTable, HtmlTableRow, etc), aunque pueda resultarte igual de tedioso o no.

Saludos
#3728
Lo que pretendes hacer no es adecuado (ya lo sabes), pero es muy sencillo, ¿será por maneras de hacerlo?... a estas alturas ya deberías saber hacer algo tan simple usando LINQ.

Teniendo esta cadena de texto:
Código (vbnet) [Seleccionar]
Dim str As String = "01 02 03 04 05 06"

Puedes utilizar LINQ para no perder la costumbre:
Código (vbnet) [Seleccionar]
Dim int32Col As IEnumerable(Of Integer) =
   From item As String In str.Split(" "c)
   Select CInt(item)


O utilizar un búcle for-each:
Código (vbnet) [Seleccionar]
Dim int32List As New List(Of Integer)
For Each item As String In str.Split(" "c)
   int32List.Add(CInt(item))
Next


...Lo que viene siendo practicamente lo mismo que esto otro:
Código (vbnet) [Seleccionar]
Dim int32List As New List(Of Integer)
Array.ForEach(Of String)(str.Split(" "c),
                        Sub(ByVal item As String)
                            int32List.Add(CInt(item))
                        End Sub)


O puedes hacerlo de lo que considero la manera más óptima:
Código (vbnet) [Seleccionar]
Dim int32Col As IEnumerable(Of Integer) =
   Array.ConvertAll(Of String, Integer)(str.Split(" "c),
                                        Function(ByVal item As String)
                                            Return Integer.Parse(item)
                                        End Function)





Para adaptarlo a los elementos de un Listbox, solo debes seguir el mismo procedimiento pero enfocado hacia una colección...

Primero creamos una referencia corta de la colección de items:
Código (vbnet) [Seleccionar]
Dim lbItems As IEnumerable(Of String) =
   ListBox1.Items.Cast(Of String)


Y entonces puedes llevar a cabo esto:
Código (vbnet) [Seleccionar]
Dim int32Col As IEnumerable(Of IEnumerable(Of Integer)) =
   From strItem As String In lbItems
   Select (From value As String In strItem.Split(" "c)
           Select CInt(value))


...o bien esto otro:
Código (vbnet) [Seleccionar]
Dim lbItems As String() =
   ListBox1.Items.Cast(Of String).ToArray

Dim int32Cols As New List(Of IEnumerable(Of Integer))
Array.ForEach(lbItems,
             Sub(item As String)
                 int32Cols.Add(Array.ConvertAll(Of String, Integer)(item.Split(" "c),
                               Function(ByVal value As String)
                                   Return Cint(value)
                               End Function))
             End Sub)


Saludos
#3729
Evita usar "Application.DoEvents" Lekim, es una muy mala práctica, lo único que consigues con eso es procesar todos los eventos de la ventana, lo que te sirve para actualizar los controles, si, pero a costa de un muy elevado tiempo de ejecución (al procesarse todos los eventos cada vez que lo usas), como también da lugar a que por ejemplo el usuario pueda enviar una señal de cierre de ventana (clickando la "X"), y se procese, pero no se finalize el programa hasta que tu código/For termine, entre otras cosas por el estilo que produce su utilización.

Saludos
#3730
Cita de: Lekim en 30 Marzo 2016, 14:22 PMYa he probado el código y ocurre igual, el mensaje se muestra antes que que termine la barra. Igual es cosa de mi compu o puede que del framework, porque no recuerdo que antes pasara.  Como solución me fabricaré mi propia barra (que ya tengo un snippet echo para eso) y listo, ya que he comprobado que funciona usando un estilo gráfico propio y el picturebox, en lugar del progressbar.

Sí, con el código que te mostré ocurre lo mismo, lo que te dije es que despues de mostrar el msgbox (unos ms despues), la barra se completará, por que le estás dejando tiempo suficiente para que se redibuje el control.

Lo intentaré explicar de una forma más simple para que se entienda mejor:
Cuando le asignas un valor del 0 al 100 a la barra de progreso, de una forma rápida como en tu código, y ves que no se completa la barra al mismo tiempo, es sencillamente por que le estás enviando actualizaciones de valor más rápido del tiempo necesario que el control o ventana necesita para procesar ese mensaje y actualizar la animación entre cada valor.

Es muy posible que si administras por ti mismo el dibujado de la barra de progreso soluciones ese problema como ya has mencionado, puesto que al hacerlo (es decir, al activar el dibujado de usuario), el control se vuelve mucho más liviano, y por ende responsivo, al perder el estilo visual de Windows de la barra de progeso, es decir, la animación 3D en general, el efecto de relleno, el brillo, pseudo-translucidez parcial (no se describirlo bien), y el movimiento del efecto de "trayectoria" luminosa:


( simplemente una imagen para entender a lo que me refiero. )

Es un claro indicativo más para demostrar que el problema está en como Microsoft administra el dibujado de ese control y el tiempo de retraso que supone, puesto que es una animación, y necesita tiempo para completarse y actualizarse.




EDITO:
En esta respuesta comento algo relacionado sobre el tema, y dejo un snippet que tal vez te podría ser de utilidad:




TL/DR:
Cita de: Lekim en 29 Marzo 2016, 23:58 PMparce que Net lo has inventado tú ¿Como sabes esas cosas? XD

No lo se absolutamente todo sobre los internals de Windows en relación a la API Win32/Win64, o Windows Forms, ni mucho menos, pero lo que se, lo he aprendido de forma autodidacta, a base de lectura e investigación, tragándome documentación extensa en MSDN para descubrir, aprender, y comprender, leyendo artículos interesantes en otras fuentes sobre todo tipo de temáticas relacionadas en general, redactados por programadores veteranos con décadas de experiencia en .Net,
y por supuesto de la práctica, pasando por fases trial-and-error como todo el mundo, y cuando he tenido que recurrir a preguntarle a personas que saben muchísimo más que yo y me han ayudado en su momento, dignos de llamarse gurús o semi-dioses del conocimiento, como por ejemplo Hans Passant (de StackOverflow).

Saludos