C# - Only Shared Printer Queues are visible from web application hosted on IIS

91 views Asked by At

I have two printers configured in System1 running on Windows Server 2016. One is a shared printer (has Print Sharing enabled in Printer Properties). Other one is not a shared printer (has Print Sharing disabled in Printer Properties).

From System2, I am trying to programatically list all print queues available on System1 using below C# code snippet.

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

When I run the above code from a console application in System2, GetPrintQueues() method returns BOTH print queues(of shared and unshared printers) present on System1. But, When I run the same code snippet from an ASP.NET webapp hosted on IIS in System2, GetPrintQueues() method returns ONLY the print queue of the shared printer present on System1.

How can I make sure that, even the web application running on IIS is able to fetch both shared & unshared print queues ?

Note: Both System1 and System2 are running with same logged on admin user, so console application runs with this user account. But, IIS application runs with a IIS user. Could this be the reason for the above issue? If so, how to fix the issue in a neat way?

1

There are 1 answers

5
Jalpa Panchal On BEST ANSWER

When you run the console application, it executes under your admin user account , and therefore it has access to all the print queues on System1. However, when you run the ASP.NET web application, it executes under the identity of the application pool in IIS, which doe snot have enough permission.

You could set the IIS application pool to use the custom account which is admin user by following below steps:

  1. Open IIS Manager, expand server node click "Application Pools"
  2. Find the application pool used by your web application, select "Advanced Settings."
  3. In the “Identity” property under the “Process Model” section, select “Custom account,” and then click "Set."
  4. Enter the username and password of an account that has sufficient privileges to access all print queues on System1.
  5. Click "OK" to save the changes and restart your application pool for the changes to take effect.

Update:

By coding you can use the impersonation in your asp.net web app:

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();
        }
    }
}

In the username password use the administrator user credential.