IIS托管的ASP.NET应用仅获取共享打印队列,如何获取全部队列?
问题描述
在Windows Server 2016系统System1中配置了两台打印机:一台为启用打印共享的共享打印机,另一台为禁用打印共享的非共享打印机。在System2中使用以下C#代码尝试获取System1上的所有打印队列:
PrintServer printServer = new PrintServer(@"\\System1"); PrintQueueCollection printQueues = server.GetPrintQueues();
控制台程序运行这段代码时,能返回System1上的全部打印队列(共享与非共享);但在System2的IIS托管ASP.NET应用中运行时,仅能返回共享打印机的队列。
需解决:如何让IIS托管的ASP.NET应用获取到共享和非共享的全部打印队列?另外,System1和System2使用同一管理员账户,控制台程序以此账户运行,而IIS应用使用IIS默认账户,这是否是问题根源?若是,如何优雅解决?
问题根源
是的,账户权限差异就是核心原因:
- 控制台程序使用本地管理员账户,该账户对远程服务器System1的打印服务拥有足够权限,可访问所有打印队列(包括非共享的)。
- IIS托管的ASP.NET默认使用IIS应用池标识(如
IIS AppPool\DefaultAppPool)或Network Service这类内置账户,这些账户访问远程资源时权限受限,仅能查看共享打印机。
优雅解决方案
1. 为应用池配置有权限的域/本地账户(推荐)
这是最安全且规范的做法:
- 打开System2的IIS管理器,找到目标ASP.NET应用对应的应用池,右键选择高级设置。
- 在标识项中选择自定义账户,点击设置,输入具备System1打印服务访问权限的管理员账户(或域账户)的用户名与密码。
- 重启应用池及ASP.NET应用,此时代码将以该高权限账户访问System1,可获取全部打印队列。
2. 为IIS内置账户分配System1的打印权限
若不想使用自定义账户,可给IIS默认使用的内置账户分配权限:
- 在System1上打开打印管理工具,定位到打印服务器下的System1节点,右键选择属性。
- 切换至安全选项卡,添加System2的内置账户(如
System2\Network Service,域环境可添加域内NETWORK SERVICE组)。 - 为该账户分配至少读取打印队列的权限(可选择“打印”“管理打印机”等权限组合)。
- 重启System1的
Spooler服务,再重启System2上的ASP.NET应用。
3. 代码层面模拟高权限访问(不推荐,安全性低)
仅当上述方案无法实施时作为临时替代:
通过账户模拟技术,让代码以高权限账户执行打印服务器访问逻辑:
// 示例:使用Impersonator类模拟高权限账户(需自行实现或引入相关类库) using (var impersonationContext = new Impersonator("管理员用户名", "域名/机器名", "密码")) { PrintServer printServer = new PrintServer(@"\\System1"); PrintQueueCollection printQueues = printServer.GetPrintQueues(); // 处理打印队列的业务逻辑 }
注意:此方式需硬编码账户密码,存在泄露风险,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Legolas21
相关产品推荐
相关产品推荐

