C# -只有共享的打印机目录在IIS上托管的Web应用程序中可见

vnjpjtjt  于 2023-11-19  发布在  C#
关注(0)|答案(1)|浏览(172)

我在Windows Server 2016上运行的System1中配置了两台打印机。一台是共享打印机(在打印机属性中启用了打印共享)。另一台不是共享打印机(在打印机属性中禁用了打印共享)。
在System2中,我尝试使用下面的C#代码片段以图解方式列出System1上可用的所有打印队列。

PrintServer printServer = new PrintServer(@"\\System1");
PrintQueueCollection printQueues = server.GetPrintQueues();

字符串
当我从System2中的控制台应用程序运行上述代码时,GetPrints()方法返回System1上存在的两个打印队列(共享和非共享打印机)。但是,当我从System2中IIS上托管的ASP.NET Web应用程序运行相同的代码片段时,GetPrints()方法仅返回System1上存在的共享打印机的打印队列。
如何确保即使是运行在IIS上的Web应用程序也能够获取共享和非共享打印队列?
注意事项:System1和System2都是使用同一个登录的管理员用户运行的,因此控制台应用程序使用此用户帐户运行。但是,IIS应用程序使用IIS用户运行。这可能是上述问题的原因吗?如果是这样,如何以简洁的方式解决这个问题?

y4ekin9u

y4ekin9u1#

当您运行控制台应用程序时,它将在您的管理员用户帐户下执行,因此它可以访问System1上的所有打印队列。但是,当您运行ASP.NET Web应用程序时,它将在IIS中的应用程序池的标识下执行,该应用程序池没有足够的权限。
您可以通过以下步骤将IIS应用程序池设置为使用管理员用户的自定义帐户:
1.打开IIS管理器,展开服务器节点,单击“应用程序配置”
1.找到您的Web应用程序使用的应用程序池,选择“高级设置”。
1.在“Process Model”部分下的“Identity”属性中,选择“Custom account”,然后单击“Set”。
1.输入具有足够权限访问System1上所有打印队列的帐户的用户名和密码。
1.单击“确定”以保存更改,并重新启动应用程序池以使更改生效。
更新:
通过编码,您可以在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();
        }
    }
}

字符串
在用户名密码中使用管理员用户凭据。

相关问题