2011-01-13 8 views
5

So come ottenere l'elenco di tutte le stampanti installate su una macchina con .Net:È possibile ottenere l'icona associata a una stampante installata tramite .Net?

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

InstalledPrinters è solo una lista di stringhe però. C'è un modo per ottenere gli oggetti della stampante installati che contengono sia il nome che l'immagine dell'icona che normalmente vedrei in "Dispositivi e stampanti" in Windows Explorer?

+0

Questa soluzione sembra essere un buon inizio, si può iniziare a giocare con P/Richiama: http: //stackoverflow.com/questions/1063874/winapi-retrieving-icons-of-current-user-printers –

risposta

2

L'icona è normalmente incorporata in uno dei file DLL o EXE principale, guarda i metodi statici System.Drawing.Icon, il link sottostante è per WinForms, è leggermente diverso con WPF dato che devi creare un ImageSource dal flusso di icone estratto.

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

+0

Ma quale * .dll richiederebbe l'icona della stampante? Ho provato a interrogare System.Printing.dll per il quale dà l'icona della dll. non le stampanti. –

+0

La dll da cercare è DDORes.dll nella directory Windows \ System32. –

0

codice C# per questo compito:

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; 
    } 
} 

Attenzione, che i nomi delle stampanti nel dizionario risultato saranno i nomi delle stampanti mostrati nella cartella di shell stampanti, e possono essere diversi dai nomi di stampante, utilizzati nella classe PrinterSettings (ad esempio, le stampanti di rete nella cartella shell di Printers possono essere visualizzate come "on" e la parola "on" dipende dalla localizzazione di Windows e può non essere il nome della rete della macchina). Non so ancora come ottenere il nome di stampante "reale" da IShellFolder per usarlo con la classe Standar PrinterSettings.

In ogni caso, questo codice carica le icone di sistema della stampante, quindi è possibile utilizzarlo per il proprio compito.

Upd: Shell32 codice della classe, utilizzato in questo codice può essere trovato qui (troppo grande per la risposta): http://pastebin.com/thJuWx45

+0

Per enumerare le stampanti in IShellFolder utilizzare meglio il metodo IShellFolder.ParseDisplayName, non EnumObjects e inviare il nome della stampante da PrinterSettings.IntalledPrinters (come "\ ServerName \ PrinterName" per stampanti di rete) a IShellFolder.ParseDisplayName param pszDisplayName, IShellFolder "Dispositivi e stampanti" lavorare con questo bene. Quindi, dopo questo è possibile enumerare i nomi di stampante reale ("\ ServerName \ PrinterName"), i nomi di visualizzazione della stampante ("PrinterName su ServerName" come stampanti elencate in "Dispositivi e stampanti") e le icone della stampante. –

Problemi correlati