You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Silverlight应用输入密码时境外用户触发白屏崩溃问题问询

Silverlight密码输入框崩溃问题排查与解决

问题现象

  • 用户在PasswordBox输入密码时,应用立即白屏崩溃
  • 仅英国境外用户(法国、中国、匈牙利等)受影响
  • 所有用户均通过企业组策略安装同一版本Silverlight(5.1.50918.0)
  • 本地无法复现故障,但已通过屏幕共享确认问题存在
  • 自定义客户端错误日志服务未捕获有效报错信息

相关代码

XAML密码控件代码

<PasswordBox 
    Name="InputPassword"
    TabIndex="2"
    InputMethod.PreferredImeState="Off"
    InputMethod.IsInputMethodEnabled="False"  
    PasswordChanged="InputPassword_PasswordChanged"
    KeyUp="InputPassword_KeyUp"
/>

后台C#核心代码

private bool _imeActive; 

public LoginView()
{
    InitializeComponent();
    System.Diagnostics.Debug.WriteLine("LoginView initialized");
    LayoutRoot.Loaded += (s, ea) => System.Windows.Browser.HtmlPage.Plugin.Focus();
    this.Loaded += new RoutedEventHandler(this.Page_Loaded);

    InputPassword.TextInputStart += (_, __) => _imeActive = false;
    InputPassword.TextInputUpdate += (_, __) => _imeActive = true;
}

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    if (InputUsername.Text == string.Empty)
    {
        InputUsername.Focus();
    }
}

private void InputPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
    try
    {
        if (_imeActive) return;
        
        var pb = sender as PasswordBox;
        if (pb == null) return;

        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            ViewModel.InputPassword = pb.Password;
            ViewModel.MsgText = string.Empty;
            var cmd = ViewModel.ClearErrorsCommand;
            if (cmd != null && cmd.CanExecute("InputPassword"))
            {
                cmd.Execute("InputPassword");
            }
        });
    }
    catch (Exception ex)
    {
        ClientErrorLogger.LogException(ex, ex.GetBaseException()?.StackTrace?.ToString());
    }
}

private void InputPassword_KeyUp(object sender, KeyEventArgs e)
{
    try
    {
        if (_imeActive) return;

        if (e.Key != Key.Enter) return;
        e.Handled = true;

        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            var cmd = ViewModel.LoginCommand;
            if (cmd != null && cmd.CanExecute(null))
            {
                cmd.Execute(null);
            }
        });
    }
    catch(Exception ex)
    {
        ClientErrorLogger.LogException(ex, ex.GetBaseException()?.StackTrace?.ToString());
    }
}

远程调试捕获的错误日志

ExceptionType: System.Exception
ManagedMemoryBytes: 3702844
System.Exception: [Arg_COMException]
Argumentumok: 
A hibakeresési erőforrás-karakterláncok nem érhetők el. Gyakran a kulcs és az argumentumok elegendő információt nyújtanak a probléma diagnosztizálásához.
   Hely: MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   Hely: MS.Internal.XcpImports.Control_Raise(Control control, IManagedPeerBase arguments, Byte nDelegate)
   Hely: System.Windows.Controls.PasswordBox.OnTextInput(TextCompositionEventArgs e)
   Hely: System.Windows.Controls.Control.OnTextInput(Control ctrl, EventArgs e)
   Hely: MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags)

注:日志中匈牙利语内容翻译为“无法访问调试资源字符串。通常键和参数已提供足够的问题诊断信息。”

已尝试的排查操作

  • 使用IEChooser.exe工具查看浏览器控制台日志
  • 本地修改区域、键盘、IME设置为非英语地区(中、法、日),无法复现问题

原因分析

从错误栈可以看出,崩溃发生在Silverlight内部的PasswordBox.OnTextInput事件触发阶段,属于底层COM异常。结合仅境外用户受影响的特征,推测核心原因是:
Silverlight 5.1.50918.0版本与非英语系统的输入法框架存在兼容性冲突。即使XAML中设置了禁用IME的属性,部分非英语系统的底层输入法服务仍会尝试与PasswordBox交互,触发未处理的COM异常导致整个应用崩溃。

本地无法复现可能是因为测试环境的系统语言包、输入法组件与境外用户的实际环境存在差异,或是企业组策略下的Silverlight部署存在隐藏的区域相关配置差异。

解决方案

方案1:移除自定义IME事件绑定

手动绑定的TextInputStart/TextInputUpdate事件可能与Silverlight内部的IME处理逻辑冲突,建议移除相关代码:

// 注释或删除以下代码
// InputPassword.TextInputStart += (_, __) => _imeActive = false;
// InputPassword.TextInputUpdate += (_, __) => _imeActive = true;
// 同时删除_imeActive变量及所有相关判断逻辑

方案2:升级Silverlight版本

申请将企业组策略中的Silverlight版本升级到5系列的最新版本,后续版本可能修复了该非英语区域的兼容性问题。

方案3:添加全局异常捕获

在应用启动时注册全局异常处理,防止单个控件的异常导致应用整体崩溃:

public App()
{
    this.UnhandledException += this.Application_UnhandledException;
}

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
    if (!System.Diagnostics.Debugger.IsAttached)
    {
        e.Handled = true;
        ClientErrorLogger.LogException(e.ExceptionObject, e.ExceptionObject.StackTrace);
        // 可添加提示用户刷新页面的逻辑
    }
}

方案4:临时替换密码控件

若上述方案无法快速生效,可使用普通TextBox模拟密码输入作为临时 workaround:

<TextBox 
    Name="InputPassword"
    TabIndex="2"
    PasswordChar="*"
    InputMethod.PreferredImeState="Off"
    InputMethod.IsInputMethodEnabled="False"
    TextChanged="InputPassword_TextChanged"
    KeyUp="InputPassword_KeyUp"
/>

注意:需确保密码内容不会被意外记录或暴露,处理好安全性问题。


内容的提问来源于stack exchange,提问作者shrek-the-third-on-dvd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 12:14:51