如何在.NET WinForms应用中获取系统密码字符并避免句柄创建错误?
问题
我在WinForms控件的构造函数中通过以下代码获取系统密码字符:
TextBox textBox = new TextBox(); textBox.UseSystemPasswordChar = true; char passwordChar = (char)NativeMethods.SendMessage(textBox.Handle, NativeMethods.EM_GETPASSWORDCHAR, IntPtr.Zero, IntPtr.Zero); textBox.Dispose();
客户反馈在执行大量并行单元测试后,这段代码出现System.ComponentModel.Win32Exception: Error creating window handle.错误,原因是大量并行测试耗尽了API资源池。请问在.NET WinForms应用中,是否有其他方法可以获取系统密码字符以避免此问题?
解决方法
以下几种方法可以避免频繁创建窗口句柄导致的资源耗尽问题:
1. 缓存系统密码字符
只在首次需要时创建一次TextBox获取密码字符,之后复用这个值,无需每次都创建新控件:
private static char? _systemPasswordChar; public static char GetSystemPasswordChar() { if (_systemPasswordChar.HasValue) return _systemPasswordChar.Value; using (var textBox = new TextBox()) { textBox.UseSystemPasswordChar = true; _systemPasswordChar = (char)NativeMethods.SendMessage(textBox.Handle, NativeMethods.EM_GETPASSWORDCHAR, IntPtr.Zero, IntPtr.Zero); } return _systemPasswordChar.Value; }
整个应用生命周期内仅创建一次TextBox句柄,彻底避免资源耗尽问题。
2. 直接读取系统注册表(无需创建控件)
系统密码字符存储在Windows注册表中,可直接读取对应项获取,完全跳过WinForms控件创建步骤:
using Microsoft.Win32; public static char GetSystemPasswordCharFromRegistry() { const string regPath = @"Control Panel\Desktop"; const string regKeyName = "PasswordChar"; using (var key = Registry.CurrentUser.OpenSubKey(regPath)) { if (key == null) return '*'; // 默认回退字符 var value = key.GetValue(regKeyName) as string; return string.IsNullOrEmpty(value) ? '*' : value[0]; } }
该注册表项对应当前用户设置的密码字符,与系统默认行为一致,用户修改设置时值会同步更新。若需实时获取最新值,可按需读取而非缓存。
3. 单元测试中复用资源
如果必须在单元测试中保留原逻辑,可以通过复用控件实例或限制并行数量减少句柄创建:
// 测试类中复用TextBox实例 private static TextBox _sharedTextBox; [ClassInitialize] public static void ClassInitialize(TestContext context) { _sharedTextBox = new TextBox(); _sharedTextBox.UseSystemPasswordChar = true; } [ClassCleanup] public static void ClassCleanup() { _sharedTextBox.Dispose(); } [TestMethod] public void TestPasswordChar() { char passwordChar = (char)NativeMethods.SendMessage(_sharedTextBox.Handle, NativeMethods.EM_GETPASSWORDCHAR, IntPtr.Zero, IntPtr.Zero); // 断言逻辑 }
内容的提问来源于stack exchange,提问作者Tecman
相关产品推荐
相关产品推荐

