WPF 带有图标的打印机列表
WPF List of printers with icons
如何制作这样的组合框?
我知道如何获取已安装打印机的列表,但我找不到如何检索图标或确定打印机、传真或应用程序之间差异的解决方案。
你应该看看这个http://msdn.microsoft.com/en-us/library/aa394363%28v=vs.85%29.aspx
第一个解决方案(最简单)
您可以更改传递给 GetPrintQueues
方法的数组。
LocalPrintServer printServer = new LocalPrintServer();
EnumeratedPrintQueueTypes[] filters = new EnumeratedPrintQueueTypes[] {
EnumeratedPrintQueueTypes.Fax
};
PrintQueueCollection printQueuesOnLocalServer =
printServer.GetPrintQueues(filters);
foreach (PrintQueue printQueue in printQueuesOnLocalServer)
{
Console.WriteLine("Printer: {0}", printQueue.Name);
}
Console.ReadLine();
在这种情况下,我正在寻找传真打印机,但如果我更改 filters
数组,我可以搜索其他内容。
第二解(最准确)
你可以这样使用Win32_Printer
class(正如JamesJGarner所建议的那样)
public void ListPrinters()
{
string query = "SELECT * from Win32_Printer";
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query);
ManagementObjectCollection managementObjectCollection = managementObjectSearcher.Get();
foreach (ManagementObject printer in managementObjectCollection)
{
Console.WriteLine(String.Format("Printer Name: {0}", printer.Properties["DeviceID"].Value));
Console.WriteLine(String.Format("Attributes: {0}", Decode((UInt32)printer.Properties["Attributes"].Value)));
}
Console.ReadLine();
}
private static Dictionary<UInt32, string> decodeDictionary = new Dictionary<uint, string>();
private static Dictionary<UInt32, string> DecodeDictionary
{
get
{
if (decodeDictionary.Keys.Count == 0)
{
decodeDictionary.Add(1, "PRINTER_ATTRIBUTE_QUEUED");
decodeDictionary.Add(2, "PRINTER_ATTRIBUTE_DIRECT");
decodeDictionary.Add(4, "PRINTER_ATTRIBUTE_DEFAULT");
decodeDictionary.Add(8, "PRINTER_ATTRIBUTE_SHARED");
decodeDictionary.Add(16, "PRINTER_ATTRIBUTE_NETWORK");
decodeDictionary.Add(32, "PRINTER_ATTRIBUTE_HIDDEN");
decodeDictionary.Add(64, "PRINTER_ATTRIBUTE_LOCAL");
decodeDictionary.Add(128, "PRINTER_ATTRIBUTE_ENABLEDEVQ");
decodeDictionary.Add(256, "PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS");
decodeDictionary.Add(512, "PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST");
decodeDictionary.Add(1024, "PRINTER_ATTRIBUTE_WORK_OFFLINE");
decodeDictionary.Add(2048, "PRINTER_ATTRIBUTE_WORK_OFFLINE");
decodeDictionary.Add(4096, "PRINTER_ATTRIBUTE_RAW_ONLY");
decodeDictionary.Add(8192, "PRINTER_ATTRIBUTE_PUBLISHED");
decodeDictionary.Add(16384, "PRINTER_ATTRIBUTE_FAX");
}
return decodeDictionary;
}
}
private static string Decode(UInt32 value)
{
List<string> attributes = new List<string>();
foreach (UInt32 key in DecodeDictionary.Keys)
{
if ((value & key) == key)
{
attributes.Add(DecodeDictionary[key]);
}
}
return String.Join(", ", attributes.ToArray());
}
方法ListPrinters
打印具有自身属性的本地 pc 打印机列表。
您可以找到here每个属性的含义。
我刚刚添加了最后一个属性(即"PRINTER_ATTRIBUTE_FAX"),这意味着打印机是传真机。
通过这种方式,您可以确定打印机之间的差异。
对于图标,我是这样做的:
If IsLocal And Not IsFax Then
If .Standard Then
IconExtractor.Extract("imageres.dll", -49, True, eintrag.Bild)
Else
IconExtractor.Extract("imageres.dll", -51, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name")
ElseIf IsLocal And IsFax Then
If .Standard Then
IconExtractor.Extract("shell32.dll", -197, True, eintrag.Bild) 'sollte ok sein 197
Else
IconExtractor.Extract("imageres.dll", -76, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name")
ElseIf Not IsLocal And IsFax Then
If .Standard Then
IconExtractor.Extract("shell32.dll", -198, True, eintrag.Bild)
Else
IconExtractor.Extract("shell32.dll", -199, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name").ToString.Replace(obj.GetPropertyValue("SystemName").ToString, "").Replace("\", "") & " on " & obj.GetPropertyValue("SystemName").ToString.Replace("\", "")
Else
If .Standard Then
IconExtractor.Extract("imageres.dll", -50, True, eintrag.Bild)
Else
IconExtractor.Extract("imageres.dll", -53, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name").ToString.Replace(obj.GetPropertyValue("SystemName").ToString, "").Replace("\", "") & " on " & obj.GetPropertyValue("SystemName").ToString.Replace("\", "")
End If
和图标
Public Class IconExtractor
Public Shared Function Extract(ByVal file As String, ByVal number As Integer, ByVal largeIcon As Boolean, ByRef Bild As ImageSource) As Boolean
Dim large As IntPtr
Dim small As IntPtr
Try
ExtractIconEx(file, number, large, small, 1)
Bild = ToImageSource(System.Drawing.Icon.FromHandle(If(largeIcon, large, small)))
DestroyIcon(small)
DestroyIcon(large)
Return True
Catch ex As Exception
Return False
End Try
End Function
Public Shared Function ToImageSource(ByVal icon As Icon) As ImageSource
Dim imageSource As ImageSource = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions())
Return imageSource
End Function
<DllImport("shell32.dll", CharSet:=CharSet.Auto)>
Shared Function ExtractIconEx(ByVal szFileName As String, ByVal nIconIndex As Integer, ByRef phiconLarge As IntPtr, ByRef phiconSmall As IntPtr, ByVal nIcons As UInteger) As UInteger
End Function
<DllImport("user32.dll", EntryPoint:="DestroyIcon")>
Public Shared Function DestroyIcon(ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
如何制作这样的组合框?
你应该看看这个http://msdn.microsoft.com/en-us/library/aa394363%28v=vs.85%29.aspx
第一个解决方案(最简单)
您可以更改传递给 GetPrintQueues
方法的数组。
LocalPrintServer printServer = new LocalPrintServer();
EnumeratedPrintQueueTypes[] filters = new EnumeratedPrintQueueTypes[] {
EnumeratedPrintQueueTypes.Fax
};
PrintQueueCollection printQueuesOnLocalServer =
printServer.GetPrintQueues(filters);
foreach (PrintQueue printQueue in printQueuesOnLocalServer)
{
Console.WriteLine("Printer: {0}", printQueue.Name);
}
Console.ReadLine();
在这种情况下,我正在寻找传真打印机,但如果我更改 filters
数组,我可以搜索其他内容。
第二解(最准确)
你可以这样使用Win32_Printer
class(正如JamesJGarner所建议的那样)
public void ListPrinters()
{
string query = "SELECT * from Win32_Printer";
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query);
ManagementObjectCollection managementObjectCollection = managementObjectSearcher.Get();
foreach (ManagementObject printer in managementObjectCollection)
{
Console.WriteLine(String.Format("Printer Name: {0}", printer.Properties["DeviceID"].Value));
Console.WriteLine(String.Format("Attributes: {0}", Decode((UInt32)printer.Properties["Attributes"].Value)));
}
Console.ReadLine();
}
private static Dictionary<UInt32, string> decodeDictionary = new Dictionary<uint, string>();
private static Dictionary<UInt32, string> DecodeDictionary
{
get
{
if (decodeDictionary.Keys.Count == 0)
{
decodeDictionary.Add(1, "PRINTER_ATTRIBUTE_QUEUED");
decodeDictionary.Add(2, "PRINTER_ATTRIBUTE_DIRECT");
decodeDictionary.Add(4, "PRINTER_ATTRIBUTE_DEFAULT");
decodeDictionary.Add(8, "PRINTER_ATTRIBUTE_SHARED");
decodeDictionary.Add(16, "PRINTER_ATTRIBUTE_NETWORK");
decodeDictionary.Add(32, "PRINTER_ATTRIBUTE_HIDDEN");
decodeDictionary.Add(64, "PRINTER_ATTRIBUTE_LOCAL");
decodeDictionary.Add(128, "PRINTER_ATTRIBUTE_ENABLEDEVQ");
decodeDictionary.Add(256, "PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS");
decodeDictionary.Add(512, "PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST");
decodeDictionary.Add(1024, "PRINTER_ATTRIBUTE_WORK_OFFLINE");
decodeDictionary.Add(2048, "PRINTER_ATTRIBUTE_WORK_OFFLINE");
decodeDictionary.Add(4096, "PRINTER_ATTRIBUTE_RAW_ONLY");
decodeDictionary.Add(8192, "PRINTER_ATTRIBUTE_PUBLISHED");
decodeDictionary.Add(16384, "PRINTER_ATTRIBUTE_FAX");
}
return decodeDictionary;
}
}
private static string Decode(UInt32 value)
{
List<string> attributes = new List<string>();
foreach (UInt32 key in DecodeDictionary.Keys)
{
if ((value & key) == key)
{
attributes.Add(DecodeDictionary[key]);
}
}
return String.Join(", ", attributes.ToArray());
}
方法ListPrinters
打印具有自身属性的本地 pc 打印机列表。
您可以找到here每个属性的含义。
我刚刚添加了最后一个属性(即"PRINTER_ATTRIBUTE_FAX"),这意味着打印机是传真机。 通过这种方式,您可以确定打印机之间的差异。
对于图标,我是这样做的:
If IsLocal And Not IsFax Then
If .Standard Then
IconExtractor.Extract("imageres.dll", -49, True, eintrag.Bild)
Else
IconExtractor.Extract("imageres.dll", -51, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name")
ElseIf IsLocal And IsFax Then
If .Standard Then
IconExtractor.Extract("shell32.dll", -197, True, eintrag.Bild) 'sollte ok sein 197
Else
IconExtractor.Extract("imageres.dll", -76, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name")
ElseIf Not IsLocal And IsFax Then
If .Standard Then
IconExtractor.Extract("shell32.dll", -198, True, eintrag.Bild)
Else
IconExtractor.Extract("shell32.dll", -199, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name").ToString.Replace(obj.GetPropertyValue("SystemName").ToString, "").Replace("\", "") & " on " & obj.GetPropertyValue("SystemName").ToString.Replace("\", "")
Else
If .Standard Then
IconExtractor.Extract("imageres.dll", -50, True, eintrag.Bild)
Else
IconExtractor.Extract("imageres.dll", -53, True, eintrag.Bild)
End If
.FriendlyName = obj.GetPropertyValue("Name").ToString.Replace(obj.GetPropertyValue("SystemName").ToString, "").Replace("\", "") & " on " & obj.GetPropertyValue("SystemName").ToString.Replace("\", "")
End If
和图标
Public Class IconExtractor
Public Shared Function Extract(ByVal file As String, ByVal number As Integer, ByVal largeIcon As Boolean, ByRef Bild As ImageSource) As Boolean
Dim large As IntPtr
Dim small As IntPtr
Try
ExtractIconEx(file, number, large, small, 1)
Bild = ToImageSource(System.Drawing.Icon.FromHandle(If(largeIcon, large, small)))
DestroyIcon(small)
DestroyIcon(large)
Return True
Catch ex As Exception
Return False
End Try
End Function
Public Shared Function ToImageSource(ByVal icon As Icon) As ImageSource
Dim imageSource As ImageSource = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions())
Return imageSource
End Function
<DllImport("shell32.dll", CharSet:=CharSet.Auto)>
Shared Function ExtractIconEx(ByVal szFileName As String, ByVal nIconIndex As Integer, ByRef phiconLarge As IntPtr, ByRef phiconSmall As IntPtr, ByVal nIcons As UInteger) As UInteger
End Function
<DllImport("user32.dll", EntryPoint:="DestroyIcon")>
Public Shared Function DestroyIcon(ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class