¿Por qué un control de contraseña se bloquea mi aplicación WPF?
-
27-10-2019 - |
Pregunta
He pasado un buen día tratando de averiguar por qué PasswordBox
me está causando tantos problemas.
Tengo una aplicación que funciona en cada máquina en la que la he probado. Ahora se ha instalado en otras máquinas, se está bloqueando cada vez que hago clic dentro del PasswordBox
.
Incluso hice una aplicación de prueba con solo un TextBox
y PasswordBox
Control para ver si el bloqueo fue causado por algún código subyacente en mi aplicación, pero este resultó no ser el caso. Hago clic en el TextBox
, y funciona bien. Me permite escribir texto dentro de él. Pero tan pronto como haga clic en el PasswordBox
, la aplicación se bloquea.
Configuré estos eventos para atrapar cualquier excepción no controlada:
Application.Current.DispatcherUnhandledException
AppDomain.CurrentDomain.UnhandledException
AppDomain.CurrentDomain.FirstChanceException
Ahora esto debería mostrarme un MessageBox
Si ocurren errores. La peor parte es que no hay errores lanzados a estos eventos.
Configuré algunos registros en mi aplicación y tengo excepciones como:
- La referencia del objeto no se establece en una instancia de un objeto
- Intento de leer o escribir en la memoria protegida. Esto a menudo es una indicación de que otra memoria es corrupta.
Había establecido un evento para el PasswordBox
Para probar si se enfocó antes de que se bloqueara y lo hizo, por lo que no creo que la excepción de referencia de objeto se refiera a la PasswordBox
control.
He estado buscando en todas partes para encontrar si alguien más ha tenido estos problemas y solo he visto problemas con el TextBox
control y sus problemas de enfoque, que se supone que se solucionarán en .NET 4.0
¡Vaya! Y eso me recuerda. Estoy usando WPF .NET 4.0.
Cualquier ayuda sería muy apreciada.
El código de prueba es:
private void Application_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
Application.Current.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler((x, y) => { ShowError(x, y); });
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler((x, y) => { ShowError(x, y); });
AppDomain.CurrentDomain.FirstChanceException += new EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs>((x, y) => { ShowError(x, y); });
}
private void ShowError(object sender, object o)
{
Exception ex = null;
if (o.GetType() == typeof(FirstChanceExceptionEventArgs))
{
ex = ((FirstChanceExceptionEventArgs)o).Exception;
}
else if (o.GetType() == typeof(DispatcherUnhandledExceptionEventArgs))
{
ex = ((DispatcherUnhandledExceptionEventArgs)o).Exception;
}
else if (o.GetType() == typeof(UnhandledExceptionEventArgs))
{
ex = (Exception)((UnhandledExceptionEventArgs)o).ExceptionObject;
}
MessageBox.Show(ex.Message + "\n\r" + ex.StackTrace, "Error at: " + ex.Source, MessageBoxButton.OK, MessageBoxImage.Error);
}
Y el xaml:
<Window x:Class="WPF_Control_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="300">
<Grid>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Width="260">
<TextBlock Text="TextBox: " TextAlignment="Right" Width="80" Height="Auto" VerticalAlignment="Center" />
<TextBox Name="textBox" Width="120" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal" Width="260">
<TextBlock Text="PasswordBox: " TextAlignment="Right" Width="80" Height="Auto" VerticalAlignment="Center" />
<PasswordBox Name="passwordBoxTest" Width="120" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Window>
Visor de eventos
Aquí está la excepción del espectador de eventos en la máquina:
Aplicación: WPF Control test.exe
Versión del marco: v4.0.30319
Descripción: La solicitud de terminación del proceso solicitada a través de System.environment.failfast (mensaje de cadena).
Mensaje: error del sistema irrecuperable.
Pila:
en System.environment.failfast (System.String)
en ms.internal.invariant.failfast (system.string, system.string)
en system.windows.media.fontfamily.get_firstfontfamily ()
en system.windows.documents.textselection.calculateCaretrectangle (system.windows.documents.itextselection, system.windows.documents.itextpointer)
en system.windows.documents.textselection.updateCaretStateWorker (System.Object)
en system.windows.documents.textselection.updatecaretstate (system.windows.documents.caretscrollmethod)
en system.windows.documents.textselection.ensureCaret (boolean, system.windows.documents.caretscrollmethod)
en system.windows.documents.textselection.system.windows.documents.itextselection.updatecaretandhighlight ()
en system.windows.documents.texteditor.Ongotkeyboardfocus (System.object, System.windows.input.KeyboardfocuschangedEventargs)
en system.windows.controls.passwordbox.Ongotkeyboardfocus (system.windows.input.keyboardfocuschangedeventargs)
en System.Windows.uielement.OngotKeyboardfocusthunk (System.Object, System.Windows.Input.KeyboardfocuschangedEventargs)
en system.windows.input.keyboardfocuschangedeventargs.invokeeventhandler (System.Delegate, System.Object)
en System.Windows.RoutedEventargs.invokeHandler (System.Delegate, System.Object)
en System.Windows.RoutedEventHandlerinfo.invokeHandler (System.Object, System.Windows.RoutEDEVENTARGS)
en system.windows.eventroute.invokeHandlersImpl (System.Object, System.Windows.RoutedEventargs, Boolean)
en system.windows.uielement.raiseeVentImpl (system.windows.dependencyObject, system.windows.routedEventargs)
en system.windows.uielement.raisetrustedevent (System.windows.RoutedEventargs)
en system.windows.uielement.raiseevent (system.windows.routedEventargs, booleano)
en system.windows.input.inputmanager.processstagingArea ()
en system.windows.input.inputmanager.processinput (system.windows.input.inputeventArgs)
en system.windows.input.keyboarddevice.changefocus (system.windows.dependencyObject, int32)
en system.windows.input.keyboarddevice.trychangeFocus (System.windows.DependencyObject, System.Windows.Input.iKeyBoardInputProvider, booleano, booleano, booleano)
en system.windows.input.keyboarddevice.focus (system.windows.dependencyObject, booleano, booleano, booleano)
en system.windows.input.keyboarddevice.focus (system.windows.iinputelement)
en system.windows.uielement.focus ()
en system.windows.documents.texteditormouse.movefocustouiscope (system.windows.documents.texteditor)
en system.windows.documents.texteditormouse.onmousedown (system.object, system.windows.input.MouseButTonventArgs)
en system.windows.controls.passwordbox.onmousedown (system.windows.input.MouseButToneVentArgs)
en system.windows.uielement.onmousedownthunk (System.object, System.windows.input.MouseButTonEventArgs)
en System.windows.input.MouseButTonVentArgs.invokeEventHandler (System.Delegate, System.Object)
en System.Windows.RoutedEventargs.invokeHandler (System.Delegate, System.Object)
en System.Windows.RoutedEventHandlerinfo.invokeHandler (System.Object, System.Windows.RoutEDEVENTARGS)
en system.windows.eventroute.invokeHandlersImpl (System.Object, System.Windows.RoutedEventargs, Boolean)
en system.windows.uielement.raiseeVentImpl (system.windows.dependencyObject, system.windows.routedEventargs)
en system.windows.uielement.raisetrustedevent (System.windows.RoutedEventargs)
en system.windows.uielement.raiseevent (system.windows.routedEventargs, booleano)
en system.windows.input.inputmanager.processstagingArea ()
en system.windows.input.inputmanager.processinput (system.windows.input.inputeventArgs)
en system.windows.input.inputProvidersite.reportinput (system.windows.input.inputReport)
en system.windows.inTerop.hwndmouseInputProvider.reportInput (intptr, system.windows.input.inputmode, int32, system.windows.input.rawmouseactions, int32, int32, int32)
en System.Windows.inTerop.HwndMouseInputProvider.FilterMessage (intptr, ms.Internal.InTerop.WindowMessage, intptr, intptr, byref boolean)
en System.Windows.InTerop.Hwndsource.InputFilTermessage (IntPTR, Int32, IntPTR, Intptr, Boolean Byref)
en ms.win32.hwndwrapper.wndproc (intptr, int32, intptr, intptr, boolean byref)
en ms.win32.hwndsubclass.dispatchercallbackoperation (system.object)
en System.windows.threading.ExceptionWrapper.InternalRealCall (System.Delegate, System.Object, INT32)
en ms.internal.threading.ExceptionFilterHelper.tryCatchwhen (System.Object, System.Delegate, System.Object, Int32, System.Delegate)
en System.windows.threading.dispatcher.invokeImpl (system.windows.threading.dispatcherpriority, system.timespan, system.delegate, system.object, int32)
en ms.win32.hwndsubclass.subclasswndproc (intptr, int32, intptr, intptr)
en ms.win32.unsafenativemethods.dispatchMessage (System.windows.inTerop.Msg Byref)
en system.windows.threading.dispatcher.pushframeImpl (system.windows.threading.dispatcherframe)
en System.windows.threading.dispatcher.pushframe (system.windows.threading.dispatcherframe)
en System.Windows.Application.Rundispatcher (System.Object)
en System.Windows.Application.Runinternal (System.Windows.Window)
en system.windows.application.run (system.windows.window)
en system.windows.application.run ()
en wpf_control_test.app.main ()
Solución
Parece que el marco .NET no puede encontrar una fuente predeterminada adecuada. No sé por qué está sucediendo esto, pero las siguientes líneas de interno código de FontFamily
Incluya la línea donde se lanza la excepción:
fontFamily = this.FindFirstFontFamilyAndFace(
ref normal, ref normal2, ref normal3);
if (fontFamily == null)
{
// NullFontFamilyCanonicalName
// = CanonicalFontFamilyReference.Create(null, "#ARIAL");
fontFamily = FontFamily.LookupFontFamily(
FontFamily.NullFontFamilyCanonicalName);
Invariant.Assert(fontFamily != null); // <- Your exception
}
Aparentemente, si no especifica una fuente, buscará una fuente basada en Arial, que no puede encontrar en esa máquina, de ahí su excepción.
Otros consejos
Tuve este mismo problema en un cuadro de 7 Windows incrustado, y como se menciona en el enlace los comentarios;
http://social.msdn.microsoft.com/forums/ar/wpf/thread/fc2c9a54-8f66-4f1a-82be-cb40ada5fba5
Simplemente copié en las siguientes fuentes al directorio "C: Windows Fonts", y el problema se resolvió;
- Arial (TrueType)
- Courier New (TrueType)
- Times New Roman (TrueType)