HELP: Cannot get network and local printers on the web server.

L

lmttag

ASP.NET 2.0 (C#) application
Intranet application (not on the Internet)
Using Windows authentication and impersonation
Windows Server 2003 (IIS6)
Server is a member server on a domain
Logged into server as a domain user that is in the local Administrators
group on the server
Workstation is on the same domain
Logged into the workstation as a domain user, which is also in the local
Administrators group on the server and workstation


From the workstation, I need to get the list of printers installed on the
server (both network and local printers). Using IE on the server, I can see
all the installed printers. However, from the workstation, also using IE, I
cannot see/get the list of printers installed on the server.

The ASP.NET application, has an .aspx page that tries to get the list of
printers on the web server (using code-behind). Again, when I run the
application using IE on the server, it works fine and I get a list of the
printers on the server. However, when I run the application from the
workstation using IE (simply pointing the URL on the server), I cannot get
the list of printers.

Below is some of the code snippets from my project. I've tried 3 different
ways, but none work. Any suggestions?


Web.config
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true"/>
...
</system.web>


..aspx.cs attempt 1
using (System.Management.ManagementClass exportedShares = new
System.Management.ManagementClass("Win32_Printer"))
{
System.Management.ManagementObjectCollection shares =
exportedShares.GetInstances();

foreach (System.Management.ManagementObject share in shares)
{
Response.Write("Name: " + share["Name"].ToString());
Response.Write("<br />");
Response.Write("Default: " +
share["Default"].ToString());
Response.Write("<br />");

if (share["Description"] == null)
{
Response.Write("Description: ");
Response.Write("<br />");
}
else
{
Response.Write("Description: " +
share["Description"].ToString());
Response.Write("<br />");
}

Response.Write("Local: " + share["Local"].ToString());
Response.Write("<br />");
Response.Write("Network: " +
share["Network"].ToString());
Response.Write("<br />");
Response.Write("Shared: " + share["Shared"].ToString());
Response.Write("<br />");

if (share["Location"] == null)
{
Response.Write("Location: ");
Response.Write("<br />");
}
else
{
Response.Write("Location: " +
share["Location"].ToString());
Response.Write("<br />");
}

if (share["ServerName"] == null)
{
Response.Write("ServerName: ");
Response.Write("<br />");
}
else
{
Response.Write("ServerName: " +
share["ServerName"].ToString());
Response.Write("<br />");
}

if (share["ShareName"] == null)
{
Response.Write("ShareName: ");
Response.Write("<br />");
}
else
{
Response.Write("ShareName: " +
share["ShareName"].ToString());
Response.Write("<br />");
}
}
}


..aspx.cs attempt 2
string computer = System.Environment.MachineName;
System.Management.ConnectionOptions co = new
System.Management.ConnectionOptions();
co.Authentication =
System.Management.AuthenticationLevel.Default;
co.Impersonation =
System.Management.ImpersonationLevel.Impersonate;
System.Management.ManagementScope ms = new
System.Management.ManagementScope("\\\\" + computer, co);
System.Management.ObjectQuery oq = new
System.Management.ObjectQuery("SELECT * FROM Win32_Printer");
System.Management.ManagementObjectSearcher mos = new
System.Management.ManagementObjectSearcher(ms, oq);
System.Management.ManagementObjectCollection moc = mos.Get();

foreach (System.Management.ManagementObject mo in moc)
{
Response.Write("Name: " + mo["Name"].ToString());
Response.Write("<br />");
Response.Write("Default: " + mo["Default"].ToString());
Response.Write("<br />");

if (mo["Description"] == null)
{
Response.Write("Description: ");
Response.Write("<br />");
}
else
{
Response.Write("Description: " +
mo["Description"].ToString());
Response.Write("<br />");
}

Response.Write("Local: " + mo["Local"].ToString());
Response.Write("<br />");
Response.Write("Network: " + mo["Network"].ToString());
Response.Write("<br />");
Response.Write("Shared: " + mo["Shared"].ToString());
Response.Write("<br />");

if (mo["Location"] == null)
{
Response.Write("Location: ");
Response.Write("<br />");
}
else
{
Response.Write("Location: " +
mo["Location"].ToString());
Response.Write("<br />");
}

if (mo["ServerName"] == null)
{
Response.Write("ServerName: ");
Response.Write("<br />");
}
else
{
Response.Write("ServerName: " +
mo["ServerName"].ToString());
Response.Write("<br />");
}

if (mo["ShareName"] == null)
{
Response.Write("ShareName: ");
Response.Write("<br />");
}
else
{
Response.Write("ShareName: " +
mo["ShareName"].ToString());
Response.Write("<br />");
}
}


..aspx.cs attempt 3
for (int i = 0; i <
System.Drawing.Printing.PrinterSettings.InstalledPrinters.Count; i++)
{
string installedPrinters =
System.Drawing.Printing.PrinterSettings.InstalledPrinters;
Response.Write("Printer Name: " + installedPrinters);
Response.Write("<br />");
}
 
S

Steven Cheng[MSFT]

Hi lmttag,

Regarding on the query printers behavior in ASP.NET web application, I have
performed some local test according to your description and did find the
symptom. And based on my research and test, here is my understanding and
suggest on this problem:

** When you configure IIS to use intergrated windows authentication(disable
anonymous access), the client security token forwarded from IIS(to ASP.NET)
is a network logon session's token. Therefore, when you use <identity
impersonate="true" /> to impersonate against this network logon token, it
won't see any printers that you can see under interactive logon user
session.

** The reason why it works when you visit the page locally on the server
machine is that when you visit the page locally on the server, IE will use
your local interactive logon session's token rather than establish a new
network logon session against IIS.

I'm not sure whether you'll want to query printers for different client
users or just want to let client users get a list of all the available
printers on a server. Is it possible for your to use a fixed account for
query printers? So far, if you want to get all the printers, you need to
create an interactive logon session and impersonate undere that session.
Here is the knowledge base article that has demonstrate the code of
programmatically create an interactive logon session and impersonate in
ASP.NET:

#How to implement impersonation in an ASP.NET application
http://support.microsoft.com/kb/306158

Also, for testing , you can use <identity impersonate="true"
userName="username" password="password" /> to specify the clear text
credential of a fixed account, this can also make the ASP.NET application
impersonate under a fixed interactive logon session that can see all the
printers available to that account. How do you think?

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Imttag,

How are you doing on this issue? Does the information and suggestion in my
last reply helps you a little? If there is anything else you wonder or we
can help, please don't hesitate to post here.


Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
L

lmttag

Hello Steven,
Thank you for the follow-up. I, unfortunately, have not been able to figure
out/fix my issue. I looked at the information you provided and tried a
couple things. But no progress yet.

From a workstation/client that is using the ASP.NET intranet app., I just
need to see a list of available printers on the server (both local printers
and any network printers). I don't need to actually send a print job or
anything like that. I simply need a list of printers, then one of the
printers in the list gets picked and I save the printer name to a database
table. It seems pretty easy in theory.

And, since we sell this ASP.NET intranet app. to our customers, I cannot
hard-code a user name and password in the web.config or in any impersonation
code. This is because the end-user customers may have different users and
passwords, and we can't force them to create some user for this purpose. If
that makes sense...

So, I'm still kind of at a loss on how to get this to work. I'm sure it's
some sort of security, permissions, etc. issue that I don't know how to get
around yet.

Any other thoughts?
Thanks!
 
S

Steven Cheng[MSFT]

Thanks for your reply Imttag,

For integrated windows authenticated user, since the security token is not
of a interactive logon, it may not get all the printer info(like a
interactive logon user). I think one possible solution would be configure
IIS to use "basic" authentication since this will require client-side to
input clear text username/password credential, and we can also configure
IIS to use interactive logon for basic authenticated user:

#Basic Authentication (IIS 6.0)
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/c
f438d2c-f9c7-4351-bf56-d2ab950d7d6e.mspx?mfr=true

is using basic authentiation an possible approach for your scenario?

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Imttag,

Any progress on this issue? If there is still anything we can help, please
feel free to post here.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top