2009-06-19 17 views
12

¿Existe una forma sencilla de enumerar todas las impresoras de red visibles en .NET? Actualmente, estoy mostrando PrintDialog para permitirle al usuario seleccionar una impresora. El problema es que también se muestran las impresoras locales (junto con XPS Document Writer y similares). Si puedo enumerar las impresoras de red yo mismo, puedo mostrar un diálogo personalizado solo con esas impresoras.¿Existe una forma .NET de enumerar todas las impresoras de red disponibles?

Gracias!

+0

AvailablePrinterInfo está en el espacio de nombres obteniendo como error No se pudo encontrar el tipo o el nombre del espacio de nombres 'AvailablePrinterInfo' (¿falta una directiva using o una referencia de ensamblaje –

Respuesta

8

conocer este código 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]); 
        } 
       } 
      } 

     } 

Actualización:

"Esta función API puede enumerar todos los recursos de la red, incluyendo servidores, estaciones de trabajo, impresoras, recursos compartidos, directorios remotos, etc. "

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=741&lngWId=10

+0

+1 Gracias! Puedo enumerar solo los nombres de las impresoras de red instaladas con unos pequeños ajustes a este código. Ahora, ¿sabe usted si puede enumerar todas las impresoras de red VISIBLES (no solo las instaladas) usando una técnica similar. – Pwninstein

+0

prueba este artículo: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=741&lngWId= 10 " Esta función API puede enumerar todos los recursos de red, incluidos servidores, estaciones de trabajo, impresoras, recursos compartidos, directorios remotos, etc. " Espero que ayude, vitoreó –

+0

excepción nula en la última declaración. –

2

PrinterSettiings.InstalledPrinters deben darle la colección que desea

+1

PrinterSettings.InstalledPrinters aún muestra no- impresoras de red, así como impresoras de documentos (PDF Writer, XPS Document Writer, etc.) – Pwninstein

9

utilizando la nueva 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); 
    } 
} 
+0

Esto solo enumera las impresoras locales, no las impresoras de red. – awe

+0

awe: prueba el código actualizado – Simon

+0

Gracias, esto funcionó perfectamente para lo que necesito +1 –

13
  • Obtener la impresora predeterminada de LocalPrintServer.DefaultPrintQueue
  • Recibe las impresoras instaladas (desde la perspectiva del usuario) de PrinterSettings.InstalledPrinters
  • enumerar la lista:
  • Cualquier impresora comenzando con \\ es una impresora de red - a fin de obtener la cola con new PrintServer("\\UNCPATH").GetPrintQueue("QueueName")
  • Cualquier impresora no comienza con \\ es una impresora local a fin de obtener con LocalPrintServer.GetQueue("Name")
  • Se puede ver que es por defecto mediante la comparación de FullName propiedad.

Nota: una impresora de red puede ser la impresora predeterminada de LocalPrintServer.DefaultPrintQueue, pero no aparece en 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); 
+0

Gracias Simon - muy útil. – PolicyWatcher

1

En otro post (https://stackoverflow.com/a/30758129/6513653) relationed a ésta, Scott Chamberlain dijo "no creo hay algo en .NET que puede hacer esto, tendrá que hacer una llamada nativa ". Después de probar todo el posible recurso .NET, creo que tiene razón. Entonces, comencé a investigar cómo el diálogo AGREGAR IMPRESORA hace su búsqueda. Usando Wireshark, descubrí que ADD PRINTER envía al menos dos tipos de paquetes a todos los hosts en la red local: dos solicitudes http/xml al puerto 3911 y tres solicitudes SNMP. enter image description here La primera solicitud SNMP es una siguiente 1.3.6.1.2.1.43, que es Printer-MIB. El segundo, es un get 1.3.6.1.4.1.2699.1.2.1.2.1.1.3 que es pmPrinterIEEE1284DeviceId de PRINTER-PORT-MONITOR-MIB. Esto es lo que más le interesa, ya que desde ADD impresora toma el nombre de la impresora. El tercero es un get 1.3.6.1.2.1.1.1.0, que es sysDescr del sistema SNMP MIB-2. Creo que la segunda solicitud de SNMP es suficiente para encontrar la mayoría de las impresoras de red en la red local, así que hice este código. Funciona para Windows Form Application y depende de SnmpSharpNet.

Editar: Estoy usando ARP Ping en lugar de Ping normal para buscar hosts activos en la red.Enlace para un proyecto de ejemplo: ListNetworks C# Project

Cuestiones relacionadas