是否有直接的方法来枚举.NET中的所有可见网络打印机?目前,我正在显示PrintDialog以允许用户选择打印机。问题是,本地打印机也会显示(与XPS Document Writer等一起)。如果我自己可以枚举网络打印机,我可以只显示那些打印机的自定义对话框。
谢谢!
答案 0 :(得分:15)
LocalPrintServer.DefaultPrintQueue
PrinterSettings.InstalledPrinters
\\
开头的打印机都是网络打印机 - 因此请使用new PrintServer("\\UNCPATH").GetPrintQueue("QueueName")
\\
开头的打印机都是本地打印机,因此请使用LocalPrintServer.GetQueue("Name")
FullName
属性来查看哪个是默认值。 注意:网络打印机可以是LocalPrintServer.DefaultPrintQueue
的默认打印机,但不会显示在LocalPrintServer.GetPrintQueues()
// get available printers
LocalPrintServer printServer = new LocalPrintServer();
PrintQueue defaultPrintQueue = printServer.DefaultPrintQueue;
// get all printers installed (from the users perspective)he t
var printerNames = PrinterSettings.InstalledPrinters;
var availablePrinters = printerNames.Cast<string>().Select(printerName =>
{
var match = Regex.Match(printerName, @"(?<machine>\\\\.*?)\\(?<queue>.*)");
PrintQueue queue;
if (match.Success)
{
queue = new PrintServer(match.Groups["machine"].Value).GetPrintQueue(match.Groups["queue"].Value);
}
else
{
queue = printServer.GetPrintQueue(printerName);
}
var capabilities = queue.GetPrintCapabilities();
return new AvailablePrinterInfo()
{
Name = printerName,
Default = queue.FullName == defaultPrintQueue.FullName,
Duplex = capabilities.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge),
Color = capabilities.OutputColorCapability.Contains(OutputColor.Color)
};
}).ToArray();
DefaultPrinter = AvailablePrinters.SingleOrDefault(x => x.Default);
答案 1 :(得分:12)
使用新的System.Printing API
using (var printServer = new PrintServer(string.Format(@"\\{0}", PrinterServerName)))
{
foreach (var queue in printServer.GetPrintQueues())
{
if (!queue.IsShared)
{
continue;
}
Debug.WriteLine(queue.Name);
}
}
答案 2 :(得分:9)
找到此代码here
private void btnGetPrinters_Click(object sender, EventArgs e)
{
// Use the ObjectQuery to get the list of configured printers
System.Management.ObjectQuery oquery =
new System.Management.ObjectQuery("SELECT * FROM Win32_Printer");
System.Management.ManagementObjectSearcher mosearcher =
new System.Management.ManagementObjectSearcher(oquery);
System.Management.ManagementObjectCollection moc = mosearcher.Get();
foreach (ManagementObject mo in moc)
{
System.Management.PropertyDataCollection pdc = mo.Properties;
foreach (System.Management.PropertyData pd in pdc)
{
if ((bool)mo["Network"])
{
cmbPrinters.Items.Add(mo[pd.Name]);
}
}
}
}
更新
“此API函数可以枚举所有网络资源,包括服务器,工作站,打印机,共享,远程目录等。”
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=741&lngWId=10
答案 3 :(得分:2)
PrinterSettiings.InstalledPrinters
应该为您提供所需的收藏
答案 4 :(得分:2)
在与此相关的另一篇文章(https://stackoverflow.com/a/30758129/6513653)中,Scott Chamberlain说:“我不相信.NET中有任何东西可以做到这一点,你需要进行本地调用”。在尝试了所有可能的.NET资源之后,我认为他是对的。 所以,我开始研究ADD PRINTER对话框如何进行搜索。使用Wireshark,我发现ADD PRINTER向本地网络中的所有主机发送至少两种类型的包:两个http / xml请求到3911端口和三个SNMP请求。 第一个SNMP请求是get-next 1.3.6.1.2.1.43,它是Printer-MIB。第二个是得到1.3.6.1.4.1.2699.1.2.1.2.1.1.3,它是PRINTER-PORT-MONITOR-MIB的pmPrinterIEEE1284DeviceId。这是最有趣的,因为ADD PRINTER占用了打印机名称。第三个是获取1.3.6.1.2.1.1.1.0,它是SNMP MIB-2系统的sysDescr。 我相信第二个SNMP请求足以找到本地网络中的大多数网络打印机,所以我做了这个代码。它适用于Windows Form Application,它取决于SnmpSharpNet。
编辑:我正在使用ARP Ping而不是普通Ping来搜索网络中的活动主机。示例项目的链接:ListNetworks C# Project
答案 5 :(得分:0)
请注意,如果您正在RDP上工作,这似乎会使事情复杂化,因为它看起来像将主机上的所有内容都导出为本地打印机一样。
如果您期望它不在RDP上以相同的方式工作,那将是一个问题。