2011-01-13 15 views
5

sé cómo obtener la lista de todas las impresoras instaladas en una máquina con .Net:¿Puedo obtener el icono asociado a una impresora instalada a través de .Net?

foreach (String printer in PrinterSettings.InstalledPrinters) 
{   
    Console.WriteLine(printer.ToString()); 
} 
Console.ReadLine(); 

InstalledPrinters es sólo una lista de cadenas sin embargo. ¿Hay alguna forma de obtener los objetos de la impresora instalados que contienen tanto el nombre como la imagen del icono que normalmente vería en "Dispositivos e impresoras" en el Explorador de Windows?

+0

Esta solución parece ser un buen comienzo, puede empezar a jugar con P/Invoca: http: //stackoverflow.com/questions/1063874/winapi-retrieving-icons-of-current-user-printers –

Respuesta

2

El icono normalmente está incrustado en cualquiera de los archivos dll o en el EXE principal, mira los métodos estáticos System.Drawing.Icon, el siguiente enlace es para WinForms, es ligeramente diferente con WPF ya que tienes que crear un ImageSource de la secuencia de iconos extraída.

How to: Extract the Icon Associated with a File in Windows Forms

+0

Pero, ¿con qué * .dll consultarías el icono de la impresora? He intentado consultar el System.Printing.dll para el cual da el ícono de la dll. no las impresoras –

+0

El DLL que se busca es DDORes.dll en el directorio Windows \ System32. –

0

C# código para esta tarea:

public static class PrinterIcons 
{ 
    public static Dictionary<string, Icon> GetPrintersWithIcons(IntPtr hwndOwner) 
    { 
     Dictionary<string, Icon> result = new Dictionary<string, Icon>(); 

     Shell32.IShellFolder iDesktopFolder = Shell32.GetDesktopFolder(); 
     try 
     { 
      IntPtr pidlPrintersFolder; 
      if (Shell32.SHGetFolderLocation(hwndOwner, (int)Shell32.CSIDL.CSIDL_PRINTERS, IntPtr.Zero, 0, out pidlPrintersFolder) == 0) 
       try 
       { 
        StringBuilder strDisplay = new StringBuilder(260); 
        Guid guidIShellFolder = Shell32.IID_IShellFolder; 
        IntPtr ptrPrintersShellFolder; 
        iDesktopFolder.BindToObject(pidlPrintersFolder, IntPtr.Zero, ref guidIShellFolder, out ptrPrintersShellFolder); 
        Object objPrintersShellFolder = Marshal.GetTypedObjectForIUnknown(ptrPrintersShellFolder, Shell32.ShellFolderType); 
        try 
        { 
         Shell32.IShellFolder printersShellFolder = (Shell32.IShellFolder)objPrintersShellFolder; 

         IntPtr ptrObjectsList; 

         printersShellFolder.EnumObjects(hwndOwner, Shell32.ESHCONTF.SHCONTF_NONFOLDERS, out ptrObjectsList); 
         Object objEnumIDList = Marshal.GetTypedObjectForIUnknown(ptrObjectsList, Shell32.EnumIDListType); 
         try 
         { 
          Shell32.IEnumIDList iEnumIDList = (Shell32.IEnumIDList)objEnumIDList; 
          IntPtr[] rgelt = new IntPtr[1]; 
          IntPtr pidlPrinter; 
          int pceltFetched; 
          Shell32.STRRET ptrString; 
          while (iEnumIDList.Next(1, rgelt, out pceltFetched) == 0 && pceltFetched == 1) 
          { 
           printersShellFolder.GetDisplayNameOf(rgelt[0], 
            Shell32.ESHGDN.SHGDN_NORMAL, out ptrString); 
           if (Shell32.StrRetToBuf(ref ptrString, rgelt[0], strDisplay, 
            (uint)strDisplay.Capacity) == 0) 
           { 
            pidlPrinter = Shell32.ILCombine(pidlPrintersFolder, rgelt[0]); 
            string printerDisplayNameInPrintersFolder = strDisplay.ToString(); 

            Shell32.SHFILEINFO shinfo = new Shell32.SHFILEINFO(); 
            Shell32.SHGetFileInfo(pidlPrinter, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), Shell32.SHGFI.PIDL | Shell32.SHGFI.AddOverlays | Shell32.SHGFI.Icon); 
            Icon printerIcon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone(); 
            Shell32.DestroyIcon(shinfo.hIcon); 

            result.Add(printerDisplayNameInPrintersFolder, printerIcon); 
           } 
          } 
         } 
         finally 
         { 
          Marshal.ReleaseComObject(objEnumIDList); 
         } 
        } 
        finally 
        { 
         Marshal.ReleaseComObject(objPrintersShellFolder); 
        } 
       } 
       finally 
       { 
        Shell32.ILFree(pidlPrintersFolder); 
       } 
     } 
     finally 
     { 
      Marshal.ReleaseComObject(iDesktopFolder); 
     } 

     return result; 
    } 
} 

cuidado, que los nombres de la impresora en el diccionario de resultado serán nombres de impresora muestran en la carpeta de shell Impresoras, y pueden ser diferentes de nombres de impresoras, usados en la clase PrinterSettings (por ejemplo, las impresoras de red en la carpeta de shell de Impresoras pueden mostrarse como "activadas", y la palabra "activada" depende de la localización de Windows y puede no ser el nombre de red de la máquina). Aún no sé cómo obtener el nombre de la impresora "real" de IShellFolder para usarlo con la clase estándar PrinterSettings.

De todos modos, este código carga los iconos del sistema de impresoras, por lo que puede usarlo para su tarea.

UPD: código de clase Shell32, que se utiliza en este código se puede encontrar aquí (demasiado grande para respuesta): http://pastebin.com/thJuWx45

+0

Para enumerar impresoras en IShellFolder mejor utilizar el método IShellFolder.ParseDisplayName, no EnumObjects, y enviar el nombre de la impresora desde PrinterSettings.IntalledPrinters (como "\ ServerName \ PrinterName" para impresoras de red) a IShellFolder.ParseDisplayName param pszDisplayName, IShellFolder "Dispositivos e impresoras" trabaja bien con esto Luego, podemos enumerar los nombres reales de las impresoras ("\ ServerName \ PrinterName"), los nombres de las impresoras ("PrinterName on ServerName" como impresoras enumeradas en "Dispositivos e impresoras") y los iconos de la impresora. –

Cuestiones relacionadas