2011-01-13 2 views
5

Ich weiß, wie die Liste der alle installierten Drucker auf einem Computer mit .NET zu erhalten:Kann ich das Symbol mit einem installierten Drucker über .Net verbinden?

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

InstalledPrinters ist nur eine Liste von Strings. Gibt es eine Möglichkeit, die installierten Druckerobjekte zu erhalten, die sowohl den Namen als auch das Symbolbild enthalten, das ich normalerweise unter "Geräte und Drucker" im Windows Explorer sehen würde?

+0

Diese Lösung einen guten Start zu sein scheint, können Sie anfangen zu spielen mit P/Ruft: http: //stackoverflow.com/questions/1063874/winapi-retrieving-icons-of-current-user-printers –

Antwort

2

Das Symbol ist normalerweise in eine der DLL-Dateien oder die Haupt-EXE eingebettet, schauen Sie sich die statischen Methoden von System.Drawing.Icon an, der folgende Link ist für WinForms, etwas anders als bei WPF, da Sie ein erstellen müssen ImageSource aus dem extrahierten Symbolstrom.

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

+0

Aber welche * .dll würden Sie für das Symbol des Druckers abfragen? Ich habe versucht, die System.Printing.dll abzufragen, für die es das Symbol der DLL gibt. nicht die Drucker. –

+0

Die DLL, nach der gesucht wird, ist DDORes.dll im Windows \ System32-Verzeichnis. –

0

C# -Code für diese Aufgabe:

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

Vorsicht, dass Druckernamen im Ergebnis Wörterbuch werden Druckernamen in Printer Shell-Ordnern angezeigt werden, und sie können von Druckernamen unterschiedlich sein können, verwendet B. in der PrinterSettings-Klasse (Netzwerkdrucker im Shell-Ordner "Printers" können als "Ein" angezeigt werden und das Wort "Ein" hängt von der Windows-Lokalisierung ab und kann nicht der Computernetzwerkname sein). Ich weiß noch nicht, wie man einen "echten" Druckernamen von IShellFolder bekommt, um ihn mit der Standard-Klasse PrinterSettings zu verwenden.

Wie auch immer, dieser Code lädt Drucker System-Icons, so dass Sie es für Ihre Aufgabe verwenden können.

Upd: Shell32 Klassencode, in diesem Code verwendet wird, kann hier gefunden werden (zu groß für Antwort): http://pastebin.com/thJuWx45

+0

Um Drucker in IShellFolder aufzuzählen, verwenden Sie besser die IShellFolder.ParseDisplayName-Methode, nicht EnumObjects, und senden Sie den Druckernamen von PrinterSettings.IntalledPrinters (z. B. "\ ServerName \ PrinterName" für Netzwerkdrucker) an IShellFolder.ParseDisplayName param pszDisplayName, IShellFolder "Geräte und Drucker" damit gut arbeiten. So können wir echte Druckernamen ("\ ServerName \ PrinterName"), Druckeranzeigenamen ("PrinterName auf ServerName" als Drucker unter "Geräte und Drucker") und Druckersymbole auflisten. –

Verwandte Themen