2011-01-13 21 views
5

Tôi biết làm thế nào để có được danh sách của tất cả các máy in được cài đặt trên một máy tính với Net:Tôi có thể nhận biểu tượng được kết hợp với máy in được cài đặt thông qua .Net không?

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

InstalledPrinters chỉ là một danh sách các chuỗi mặc dù. Có cách nào để có được các đối tượng máy in được cài đặt có chứa cả tên và hình ảnh biểu tượng mà tôi thường thấy trong "Thiết bị và Máy in" trong Windows Explorer không?

+0

Giải pháp này có vẻ là một khởi đầu tốt, bạn có thể bắt đầu chơi với P/Gọi ra: http: //stackoverflow.com/questions/1063874/winapi-retrieving-icons-of-current-user-printers –

Trả lời

2

Biểu tượng thường được nhúng vào một trong các tệp dll hoặc EXE chính, xem các phương thức tĩnh System.Drawing.Icon, liên kết bên dưới dành cho WinForms, hơi khác với WPF vì bạn phải tạo ImageSource từ luồng biểu tượng được trích xuất.

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

+0

Nhưng, * .dll nào bạn sẽ truy vấn biểu tượng của máy in? Tôi đã thử truy vấn System.Printing.dll mà nó cung cấp cho biểu tượng của dll. không phải máy in. –

+0

Dll để tìm kiếm là DDORes.dll trong thư mục Windows \ System32. –

0

C# mã cho nhiệm vụ này:

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

Hãy coi chừng, mà tên máy in trong từ điển kết quả sẽ được tên máy in thể hiện trong thư mục vỏ máy in, và họ có thể khác với tên máy in, sử dụng trong lớp PrinterSettings (ví dụ, máy in mạng trong thư mục trình bao Máy in có thể được hiển thị là "bật" và từ "bật" phụ thuộc vào bản địa hóa cửa sổ và có thể không phải là tên mạng máy). Tôi không biết làm thế nào để có được tên máy in "thực" từ IShellFolder để sử dụng nó với standart PrinterSettings lớp.

Dù sao, mã này sẽ tải các biểu tượng hệ thống máy in, để bạn có thể sử dụng nó cho công việc của mình.

UPD: shell32 mã lớp, sử dụng trong mã này có thể được tìm thấy ở đây (quá lớn cho câu trả lời): http://pastebin.com/thJuWx45

+0

Để liệt kê các máy in trong IShellFolder sử dụng phương pháp IShellFolder.ParseDisplayName tốt hơn, không phải EnumObjects và gửi tên máy in từ PrinterSettings.IntalledPrinters (chẳng hạn như "\ ServerName \ PrinterName" cho máy in mạng) tới IShellFolder.ParseDisplayName param pszDisplayName, IShellFolder "Thiết bị và máy in" làm việc với cái giếng này. Vì vậy, sau này chúng ta có thể liệt kê tên máy in thực ("\ Tên máy chủ \ Tên máy in"), tên hiển thị máy in ("PrinterName on ServerName" là máy in được liệt kê trong "Thiết bị và máy in") và biểu tượng máy in. –

Các vấn đề liên quan