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

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Instrucción que es ignorada
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Instrucción que es ignorada  (Leído 4,219 veces)
zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Instrucción que es ignorada
« en: 23 Junio 2015, 03:21 am »

La verdad es que tengo un poco de experiencia usando Java y C#, y aunque aún no me acostumbro a la sintaxis de VB, lo siguiente me parece muy extraño.

1. La imagen siguiente muestra la instanciación de un objeto de mi clase Conexion (la estoy creando con la intención de facilitarme las cosas para futuras conexiones).
Le indico el nombre de la BD e invoco un método para hacer uso de dicho objeto.

(En el constructor creo un SqlConnection y un SqlAdapter en base a tal conexión)

2. Este es el método invocado desde lo que se muestra en la imagen 1 (que sería el evento Load de mi formulario). Y donde aparece la flecha es a donde aparentemente nunca se llega. El MessageBox nunca muestra el número 2. Antes de invocar a consultar estaba un MessageBox que mostraba el "1" y sí que sale, pero no el "2".


3. Este método consultar está dentro de mi clase Conexion. Se muestra "1a" y "1b" pero "1c" jamás se muestra. Mientras se muestran estos MessageBox el formulario (que es para editar/agregar productos) no se muestra (solo se ve el form principal desde el que se invoca).
Luego de que acepto el mensaje "1b", aparece el dichoso formulario y sin congelarse funciona bien. ¡ ¿Pero qué pasó con "1c" y "2" y "3"? !


Espero puedan darme una ayuda.
Gracias.


En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Re: Instrucción que es ignorada
« Respuesta #1 en: 23 Junio 2015, 03:42 am »

Soy un tipo realmente tonto :silbar:

No estaba inicializando el objeto DataTable.

De todas formas, si yo no usaba un Try Catch el programa no me advertía.
¿Por qué? En Java algunas excepciones deben tratarse obligatoriamente con un try/catch, y otras no, pero si ocurren, se notifica.

¿En VB tengo que adivinar qué instrucciones pueden generar excepciones?
¿O tal vez exagerar y encerrar todo en Try Catch's?

Gracias :s


En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.809



Ver Perfil
Re: Instrucción que es ignorada
« Respuesta #2 en: 23 Junio 2015, 04:17 am »

¿Por qué? En Java algunas excepciones deben tratarse obligatoriamente con un try/catch, y otras no, pero si ocurren, se notifica.

¿En VB tengo que adivinar qué instrucciones pueden generar excepciones?

No, cómo en Java, si no controlas una excepción, dicha excepción se lanzará/notificará.

Lo que te ocurre es debido a estos dos motivos:
1. Estás compilando la app bajo x64 (o AnyCPU)
2. Estás llamando al método que provoca dicha excepción (consultartipos) precisamente en la parte crítica de la inicialización y creación de la ventana del form.

El problema es que cuando esas dos condiciones se dan (la primera condición no la puedo confirmar si no lo especificas, pero voy a suponer que si), el debugger de VisualStudio es incapaz de controlar correctamente las excepciones que se provoquen durante el evento Form.Load bajo una aplicación x64/Neutral, por ende, nunca debes añadir código "inseguro" al método que se suscribe al evento Form.Load cómo estás haciendo aquí, ya que cualquier posible excepción será encontrada pero el tipo de excepción y el mensaje de error no te será notificado correctamente en la IDE (a menos que compiles la aplicación bajo x86):

Citar

Generalmente debes evitar usar ese método para añadir la lógica de tu código; primero deja que se cargue la ventana, y entonces, si hay alguna excepción se te notificará correctamente.

El evento digamos "After Load" sería el evento Form.Shown:

Código
  1. public class form2: inherits form
  2.  
  3.    Private Sub Form2_Shown(ByVal sender As Object, ByVal e As EventArgs) _
  4.    Handles MyBase.Shown
  5.  
  6.        ' Causar una excepción intencionada:
  7.        Dim [error] As Integer = Convert.ToInt32("Hello World!")
  8.  
  9.    End Sub
  10.  
  11. end class

Tambien puedes usar el constructor de la class si prefieres inicializar lo que tengas que inicializar antes de cargar la ventana del Form, aquí las excepciones también te serán notificadas correctamente.

Código
  1. public class form2: inherits form
  2.  
  3.    Public Sub New()
  4.  
  5.        ' This call is required by the designer.
  6.        InitializeComponent()
  7.  
  8.        ' Add any initialization after the InitializeComponent() call.
  9.  
  10.        ' Causar una excepción intencionada:
  11.        Dim [error] As Integer = Convert.ToInt32("Hello World!")
  12.  
  13.    End Sub
  14.  
  15. end class

EDITO:
Lo que yo suelo hacer cuando me encuentro en circunstancias "inseguras" es cargar el form de manera "invisible" y luego en el evento Form.Shown devolverle la visibilidad al Form:

( Solo es un tip, nada realmente importante )

Código
  1. Public Class Form2 : Inherits Form
  2.  
  3.    Private Sub Form2_Load(ByVal sender As Object, ByVal e As EventArgs) _
  4.    Handles MyBase.Load
  5.  
  6.        Me.Opacity = 0.0R
  7.  
  8.    End Sub
  9.  
  10.    Private Sub Form2_Shown(ByVal sender As Object, ByVal e As EventArgs) _
  11.    Handles MyBase.Shown
  12.  
  13.        Try ' Causar una excepción intencionada:
  14.            Dim [error] As Integer = Convert.ToInt32("Hello World!")
  15.  
  16.        Catch ex As Exception
  17.            Throw
  18.  
  19.        End Try
  20.  
  21.        Me.Opacity = 1.0R
  22.  
  23.    End Sub
  24.  
  25. End Class

Saludos!
« Última modificación: 23 Junio 2015, 04:34 am por Eleкtro » En línea

zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Re: Instrucción que es ignorada
« Respuesta #3 en: 26 Junio 2015, 03:14 am »

Lo que te ocurre es debido a estos dos motivos:
1. Estás compilando la app bajo x64 (o AnyCPU)
2. Estás llamando al método que provoca dicha excepción (consultartipos) precisamente en la parte crítica de la inicialización y creación de la ventana del form.
¿Si compilo bajo x64 significa que el Release de la aplicación solo podría ejecutarse en ordenadores de 64 bits? Una vez leí que x86 era lo mismo que x32, pero mi ordenador es de 64 bits y al abrir el proyecto se muestra esto:


[...] nunca debes añadir código "inseguro" al método que se suscribe al evento Form.Load cómo estás haciendo aquí, ya que cualquier posible excepción será encontrada pero el tipo de excepción y el mensaje de error no te será notificado correctamente en la IDE [...]

Generalmente debes evitar usar ese método para añadir la lógica de tu código; primero deja que se cargue la ventana, y entonces, si hay alguna excepción se te notificará correctamente.

El evento digamos "After Load" sería el evento Form.Shown:
[...]
En Java por alguna razón me acostumbré a escribir "código inicial" para los formularios en el constructor... pero como en VC++ al dar doble click sobre el formulario cargaba un método asociado al evento Load, creí que era lo correcto.

Tambien puedes usar el constructor de la class
Sí lo intenté, pero el contenido de la ventana no cargaba. Luego noté que hacía falta usar InitializeComponent(), como usted lo menciona.

Respecto a lo que escribió en su post al editar... ese tip lo hace considerando de que quiero escribir "código inicial" que pueda cerrar la ventana en algunos casos y que quiero que la ventana no llegue a observarse nunca si tales casos ocrreun, ¿verdad?

Muchas gracias por responder.
En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.809



Ver Perfil
Re: Instrucción que es ignorada
« Respuesta #4 en: 26 Junio 2015, 06:58 am »

¿Si compilo bajo x64 significa que el Release de la aplicación solo podría ejecutarse en ordenadores de 64 bits?

Si compilas para x64 significa que estás haciendo la app compatible unicamente para Windows de 64 Bits, ya estés generando la compilación en modo Debug o en modo Release (obvio)



Una vez leí que x86 era lo mismo que x32

x86 = 32 Bits.
x64 = 64 Bits.

x32 = NADA.
Es un término incorrecto que tiende a ser utilizado en el sentido de querer referirse a "32-bit", pero por simple desconocimiento del término adecuado.
El término x32 tendría sentido por ejemplo si estuvieramos hablando de Linux (x32 ABI).



mi ordenador es de 64 bits y al abrir el proyecto se muestra esto

Ahá, es por que has elegido el modo Release a 32 Bits.

Puedes modificar la arquitectura a 64 Bits o Neutral (AnyCPU) en cualquier momento, desde ahí y también en la pestaña "Compile" de las propiedades de la solución de Visual Studio (En el explorador de soluciones -> Click derecho en el nombre de la solución "WES II" -> "Properties").

Nota: Si compilas en modo Neutral (es decir, AnyCPU), cómo estás bajo un Windows de 64 Bits entonces se te ejecutará la versión de 64 Bits (aunque, cabe mencionar que se puede especificar que haga lo opuesto).



En Java por alguna razón me acostumbré a escribir "código inicial" para los formularios en el constructor... pero como en VC++ al dar doble click sobre el formulario cargaba un método asociado al evento Load, creí que era lo correcto.

No, no es incorrecto, simplemente es innecesario ...mientras las circunstancias no requieran que añadas un Conctructor.

Ten en cuenta que Visual Studio es la IDE más completa, elaborada y optimizada para el desarrollador (indiferentemente de sus lenguajes soportados), la IDE siempre va a intentar automatizarte las tareas más comunes... cómo la que has comentado, pero eso no significa que manipular el código auto-generado por Visual Studio sea algo incorrecto, siempre que sepas lo que estás haciendo, claro está.

Sí lo intenté, pero el contenido de la ventana no cargaba. Luego noté que hacía falta usar InitializeComponent(), como usted lo menciona.

Claro, si te fijas verás que el método InitializeComponent es un método que contiene código auto-generado que está en la Class X.Designer.vb (donde "X" sería el nombre del Form), donde se inicializan todos los objetos/controles del Form y se le asignan los valores de las propiedades por defecto y las que hayas modificado en tiempo de diseño (en el constructor de la GUI), si no llamas a ese método ...entonces no hay Form xD.

Por si no lo sabias, es suficiente con que escribas public sub new, le das a la tecla Enter, y Visual Studio ya te genera este código:

Código
  1. Public Sub New()
  2.  
  3.    ' This call is required by the designer.
  4.    InitializeComponent()
  5.  
  6.    ' Add any initialization after the InitializeComponent() call.
  7.  
  8. End Sub

El mismo "truco" (si se le puede llamar así) también lo puedes aplicar al declarar implementaciones, por ejemplo:

Escribir public class form2 : implements idisposable + pulsar tecla Enter, generará este código:

Código
  1. Public Class form2 : Implements idisposable
  2.  
  3. #Region "IDisposable Support"
  4.    Private disposedValue As Boolean ' To detect redundant calls
  5.  
  6.    ' IDisposable
  7.    Protected Overridable Sub Dispose(disposing As Boolean)
  8.        If Not Me.disposedValue Then
  9.            If disposing Then
  10.                ' TODO: dispose managed state (managed objects).
  11.            End If
  12.  
  13.            ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
  14.            ' TODO: set large fields to null.
  15.        End If
  16.        Me.disposedValue = True
  17.    End Sub
  18.  
  19.    ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
  20.    'Protected Overrides Sub Finalize()
  21.    '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
  22.    '    Dispose(False)
  23.    '    MyBase.Finalize()
  24.    'End Sub
  25.  
  26.    ' This code added by Visual Basic to correctly implement the disposable pattern.
  27.    Public Sub Dispose() Implements IDisposable.Dispose
  28.        ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
  29.        Dispose(True)
  30.        GC.SuppressFinalize(Me)
  31.    End Sub
  32. #End Region
  33.  
  34. End Class



ese tip lo hace considerando de que quiero escribir "código inicial" que pueda cerrar la ventana en algunos casos y que quiero que la ventana no llegue a observarse nunca si tales casos ocrreun, ¿verdad?

Sí, por que de otro modo, si intentases cerrar el Form en el Constructor no podrías cerrarlo ya que al llamar al método Form.Close se intentaría liberar (llamando internamente al método Form.Dispose) un Form que todavía no ha sido inicializado, y eso lanzaría una excepción.

Y si lo intentases en el método que controla el evento Form.Load bajo una app x64 y ocurriese la excepción que mencionaste pues... ya sabes lo que pasaría.

Así que ...sí, pienso que lo mejor sería ejecutar esas instrucciones en el método que controla el evento Form.Shown.

De todas formas, si ahora ya estás controlando la excepción que mencionaste, es decir, si la tienes encerrada un bloque Try/Catch, entonces si que puedes usar el evento Form.Load para cerrar el form (sin que sea visible ni nada), o suplantar el método Form.OnLoad o Form.OnControlCreated, cómo te muestro en este ejemplo:

Código
  1. Public NotInheritable Class Form2 : Inherits Form
  2.  
  3.    <DebuggerStepThrough>
  4.    Protected Overrides Sub OnLoad(e As EventArgs)
  5.  
  6.        Me.MyMethod()
  7.        MyBase.OnLoad(e)
  8.  
  9.    End Sub
  10.  
  11.    <DebuggerStepThrough>
  12.    Private Sub MyMethod()
  13.  
  14.        Try
  15.            Throw New Exception(message:="Excepción intencionada.")
  16.  
  17.        Catch ' ex As Exception
  18.            MyBase.Close()
  19.  
  20.        End Try
  21.  
  22.    End Sub
  23.  
  24. End Class

Saludos!
« Última modificación: 26 Junio 2015, 07:17 am por Eleкtro » En línea

zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Re: Instrucción que es ignorada
« Respuesta #5 en: 26 Junio 2015, 08:00 am »

Si compilas para x64 significa que estás haciendo la app compatible unicamente para Windows de 64 Bit
¿Y si compilo para x86 será compatible tanto para windows de 32 como 64 bits?



Respecto a modificar la arquitectura, por el contrario, no debería hacerlo, ¿verdad?
Usted anteriormente comentó que si es de x64 no detecta correctamente las excepciones.



Ten en cuenta que Visual Studio es la IDE más completa, elaborada y optimizada para el desarrollador (indiferentemente de sus lenguajes soportados), la IDE siempre va a intentar automatizarte las tareas más comunes... cómo la que has comentado, pero eso no significa que manipular el código auto-generado por Visual Studio sea algo incorrecto, siempre que sepas lo que estás haciendo, claro está.

Por si no lo sabias, es suficiente con que escribas public sub new, le das a la tecla Enter, y Visual Studio ya te genera este código [...]
Okay. Me parece que había copiado el constructor que tenía en otra clase para evitar escribir.



De todas formas, si ahora ya estás controlando la excepción que mencionaste, es decir, si la tienes encerrada un bloque Try/Catch, entonces si que puedes usar el evento Form.Load para cerrar el form (sin que sea visible ni nada), o suplantar el método Form.OnLoad o Form.OnControlCreated, cómo te muestro en este ejemplo [...]
En conclusión, VB sí detecta las excepciones que ocurren y que no son controladas, pero no lo hace si dichas excepciones ocurren en el evento Load.
Muy aparte, si uso try/catch su funcionamiento siempre es adecuado, es decir, advierte excepciones en cualquier parte del prgrama.

Gracias nuevamente.

PD: He creado una clase Conexion para usarla en todo lo referente a consultar/ejecutar operaciones sobre una BD en SqlServer. Tengo algunas preguntas sobre qué es lo más recomendable, creo que haré un nuevo hilo para ello.
En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.809



Ver Perfil
Re: Instrucción que es ignorada
« Respuesta #6 en: 26 Junio 2015, 09:49 am »

¿Y si compilo para x86 será compatible tanto para windows de 32 como 64 bits?

Si, un S.O de 64 Bits puede correr aplicaciones de 32 Bits.



Respecto a modificar la arquitectura, por el contrario, no debería hacerlo, ¿verdad?

En tu caso no es necesario modificarla. deberías compilar en AnyCpu o en x86.



Usted anteriormente comentó que si es de x64 no detecta correctamente las excepciones.

En conclusión, VB sí detecta las excepciones que ocurren y que no son controladas, pero no lo hace si dichas excepciones ocurren en el evento Load.

No dije eso exactamente, lo que intenté explicarte es que debido a la naturaleza por parte de cómo el compiler trabaja durante ese paso específico y bajo x64, si añades código "inseguro" en el método suscrito al evento Form.Load y se produce una excepción, aunque la exepción se intercepte internamente, no te saldrá ningún mensaje de error en Visual Studio, y con eso pretendía que entendieras que al hacer lo que estabas haciendo, estabas siguiendo una mala práctica que debes evitar.

De todas formas cabe mencionar que cuando eso ocurre, la linea de la instrucción se resaltará (se eligirá esa linea aunque no aparezca ningún mensaje de error), y siempre puedes revisar el call stack manualmente para analizar lo ocurrido e intentar depurarlo.

Pero simplemente no uses ese evento Form.Load para añadir código de ese tipo, usa el evento Form.Shown por ejemplo, cómo ya dije.



PD: He creado una clase Conexion para usarla en todo lo referente a consultar/ejecutar operaciones sobre una BD en SqlServer. Tengo algunas preguntas sobre qué es lo más recomendable, creo que haré un nuevo hilo para ello.

No me manejo con SQL, pero espero que puedas resolver el problema que tengas.

Saludos!
« Última modificación: 26 Junio 2015, 09:56 am por Eleкtro » En línea

zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Re: Instrucción que es ignorada
« Respuesta #7 en: 7 Julio 2015, 20:51 pm »

[...]Pero simplemente no uses ese evento Form.Load para añadir código de ese tipo, usa el evento Form.Shown por ejemplo, cómo ya dije.
[...]

Como había corregido el problema continuaba usando el evento Load, pero ocurrió nuevamente otro error... no comprendía la razón, cambié el evento por Shown y la excepción saltó a la vista. Muchas gracias !

PD: En VC++ y Java, si necesitaba cambiar un evento por otro debía borrar el método autogenerado y volver a crear otro con ayuda del IDE. En VB ha bastado con cambiar el nombre del evento textualmente. La keyword "Handles" parece muy útil.
En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Equivalencia C a ASM de una instrucción.
Electrónica
Meta 3 6,766 Último mensaje 19 Octubre 2008, 06:24 am
por MARCO_RECARGADO
se atasca en una instruccion
Java
Tyrz 9 5,656 Último mensaje 21 Enero 2011, 20:57 pm
por kasiko
Instrucción % en C++?
Programación General
.:UND3R:. 1 2,344 Último mensaje 17 Enero 2012, 16:49 pm
por pucheto
Instruccion if
Programación C/C++
BJM 3 2,101 Último mensaje 22 Octubre 2012, 17:48 pm
por rir3760
Instruccion sscanf [C]
Programación C/C++
oblivionxor 6 2,766 Último mensaje 26 Febrero 2013, 20:36 pm
por oblivionxor
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines