提问人:Legolas21 提问时间:10/26/2023 更新时间:10/27/2023 访问量:51
C# - IIS 上托管的 Web 应用程序仅显示共享打印机队列
C# - Only Shared Printer Queues are visible from web application hosted on IIS
问:
我在 Windows Server 2016 上运行的 System1 中配置了两台打印机。一种是共享打印机(在打印机属性中启用了打印共享)。另一个不是共享打印机(在打印机属性中禁用了打印共享)。
在 System2 中,我尝试使用以下 C# 代码片段以编程方式列出 System1 上可用的所有打印队列。
PrintServer printServer = new PrintServer(@"\\System1");
PrintQueueCollection printQueues = server.GetPrintQueues();
当我从 System2 中的控制台应用程序运行上述代码时,GetPrintQueues() 方法返回 System1 上存在的两个打印队列(共享和非共享打印机)。但是,当我从 System2 中 IIS 上托管的 ASP.NET Web 应用程序运行相同的代码片段时,GetPrintQueues() 方法仅返回 System1 上存在的共享打印机的打印队列。
我怎样才能确保,即使是在IIS上运行的Web应用程序也能够获取共享和非共享的打印队列?
注意:System1 和 System2 都使用相同的登录管理员用户运行,因此控制台应用程序使用此用户帐户运行。但是,IIS 应用程序使用 IIS 用户运行。这可能是上述问题的原因吗?如果是这样,如何以简洁的方式解决问题?
答:
当您运行控制台应用程序时,它会在您的管理员用户帐户下执行,因此它有权访问 System1 上的所有打印队列。但是,当您运行 ASP.NET Web 应用程序时,它将在 IIS 中应用程序池的标识下执行,该应用程序池没有足够的权限。
您可以按照以下步骤将 IIS 应用程序池设置为使用自定义帐户,该帐户是管理员用户:
- 打开 IIS 管理器,展开服务器节点,单击“应用程序池”
- 找到 Web 应用程序使用的应用程序池,选择“高级设置”。
- 在“进程模型”部分下的“标识”属性中,选择“自定义帐户”,然后单击“设置”。
- 输入具有足够权限访问 System1 上所有打印队列的帐户的用户名和密码。
- 单击“确定”保存更改并重新启动应用程序池以使更改生效。
更新:
通过编码,可以在 asp.net Web 应用中使用模拟:
using System.Security.Principal;
using System.Runtime.InteropServices;
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
...
SafeTokenHandle safeTokenHandle;
bool returnValue = LogonUser("username", "domain", "password",
2, 0, out safeTokenHandle);
if (returnValue)
{
using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
{
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
PrintServer printServer = new PrintServer(@"\\System1");
PrintQueueCollection printQueues = printServer.GetPrintQueues();
}
}
}
在用户名密码中,使用管理员用户凭据。
评论
PrintServer
评论
PrintServer