Есть ли способ .NET перечислять все доступные сетевые принтеры?
Есть ли простой способ перечислить все видимые сетевые принтеры в .NET? В настоящее время я показываю PrintDialog, чтобы разрешить пользователю выбирать принтер. Проблема заключается в том, что отображаются локальные принтеры (вместе с XPS Document Writer и т.п.). Если я могу самостоятельно перечислять сетевые принтеры, я могу показать пользовательский диалог только с этими принтерами.
Спасибо!!
Ответы
Ответ 1
нашел этот код здесь
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]);
}
}
}
}
Update:
"Эта функция API может перечислять все сетевые ресурсы, включая серверы, рабочие станции, принтеры, общие папки, удаленные каталоги и т.д."
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=741&lngWId=10
Ответ 2
- Получите принтер по умолчанию с
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);
Ответ 3
с использованием нового API System.Printing
using (var printServer = new PrintServer(string.Format(@"\\{0}", PrinterServerName)))
{
foreach (var queue in printServer.GetPrintQueues())
{
if (!queue.IsShared)
{
continue;
}
Debug.WriteLine(queue.Name);
}
}
Ответ 4
PrinterSettiings.InstalledPrinters
должны предоставить вам PrinterSettiings.InstalledPrinters
вам коллекцию
Ответ 5
В другом посте (fooobar.com/questions/422218/...), связанном с этим, Скотт Чемберлен сказал: "Я не верю, что в .NET есть что-то, что может сделать это, вам нужно будет сделать нативный вызов". После того, как опробовать все возможные ресурсы .NET, я думаю, что он прав.
Итак, я начал исследовать, как диалог ADD PRINTER выполняет поиск. Используя Wireshark, я обнаружил, что ADD PRINTER отправляет по крайней мере два типа пакетов на все хосты в локальной сети: два запроса http/xml на порт 3911 и три запроса SNMP.
Первым запросом SNMP является get-next 1.3.6.1.2.1.43, который представляет собой Printer-MIB. Вторым является get 1.3.6.1.4.1.2699.1.2.1.2.1.1.3, который представляет собой pmPrinterIEEE1284DeviceId PRINTER-PORT-MONITOR-MIB. Это наиболее интересно, потому что именно там ADD PRINTER берет имя принтера. Третий - это get 1.3.6.1.2.1.1.1.0, который является sysDescr системы SNMP MIB-2.
Я действительно считаю, что второго запроса SNMP достаточно, чтобы найти большинство сетевых принтеров в локальной сети, поэтому я сделал этот код. Он работает для приложения Windows Form и зависит от SnmpSharpNet.
Редактировать: я использую ARP Ping вместо обычного Ping для поиска активных хостов в сети. Ссылка на пример проекта: ListNetworks С# Project
Ответ 6
Обратите внимание, что если вы работаете над RDP, это может усложнить ситуацию, потому что похоже, что он просто экспортирует все данные на хост в качестве локального принтера.
Что тогда является проблемой, если вы ожидаете, что он будет работать так же, когда не на RDP.