为何Windows11下ASP.NET C#需重启才能正确检测默认打印机?
编辑开始 2023/06/08 - 不久后我将删除此问题
将程序部署到Windows Server 2019后问题消失,看来该问题仅出现在Windows 11系统中……非常令人困扰。
编辑结束
Windows 11下ASP.NET调试模式无法实时检测默认打印机更改
在Windows 11专业版系统上,通过Visual Studio 2022以调试模式运行ASP.NET网站时,无法可靠获取最新设置的默认打印机。Windows的打印机信息缓存机制导致修改默认打印机后,现有代码仍返回系统重启时的旧值,仅重启系统能解决,但重启成本过高。
已尝试的检测方法
方法1:WMI查询
using System.Management; ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer"); ManagementObjectCollection printerCollection = searcher.Get(); string defaultPrinterName = string.Empty; foreach (ManagementObject printer in printerCollection) { bool isDefault = (bool)printer["Default"]; if (isDefault) { defaultPrinterName = printer["Name"].ToString(); } }
方法2:PrinterSettings类
PrinterSettings printerSettings = new PrinterSettings(); string defaultPrinterName = printerSettings.PrinterName;
问题表现
- 修改现有打印机的默认状态后,上述两种方法均返回重启时的旧默认打印机,仅系统重启后能获取最新值。
- 安装新打印机并设为默认时,无需重启即可检测到新默认打印机。
- 已尝试重启打印后台处理程序服务、打印机扩展和通知服务,重启IIS应用程序池,重启Visual Studio并重新构建,均无效。
解决方案
1. 调用Win32 API绕过.NET缓存
直接使用系统底层APIGetDefaultPrinter获取最新默认打印机,绕过.NET框架的缓存机制:
using System.Runtime.InteropServices; public static class PrinterHelper { [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref int pcchBuffer); public static string GetCurrentDefaultPrinter() { int bufferSize = 256; StringBuilder printerName = new StringBuilder(bufferSize); // 第一次尝试获取 if (GetDefaultPrinter(printerName, ref bufferSize)) { return printerName.ToString(); } // 缓冲区不足时扩容重试 printerName.Capacity = bufferSize; if (GetDefaultPrinter(printerName, ref bufferSize)) { return printerName.ToString(); } return string.Empty; } }
调用PrinterHelper.GetCurrentDefaultPrinter()即可实时获取最新的默认打印机名称。
2. 手动清除系统打印机缓存
停止打印后台处理程序后删除缓存文件,再重启服务:
- 打开管理员权限的命令提示符
- 执行命令停止服务:
net stop spooler - 删除
C:\Windows\System32\spool\PRINTERS目录下的所有文件 - 执行命令重启服务:
net start spooler
该操作会清除系统层面的打印机缓存,之后程序即可获取最新设置。
3. 规避调试进程缓存问题
Visual Studio调试模式下,ASP.NET进程可能保留了启动时的打印机缓存,可尝试:
- 完全关闭Visual Studio,重新打开项目并启动调试会话
- 发布网站到本地IIS运行,替代Visual Studio内置的调试服务器
内容的提问来源于stack exchange,提问作者BLoB
相关产品推荐
相关产品推荐

