.net 4.0 - C# 打印机属性 WMI

本文关键字:打印机 属性 WMI net | 更新日期: 2023-09-27 17:55:12

您好,我有以下代码来检索打印机属性:

string printerName = "PrinterName";
string query = string.Format("SELECT * from Win32_Printer " 
                                + "WHERE Name LIKE '%{0}'",
                             printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject printer in coll)
{
    foreach (PropertyData property in printer.Properties)
    {
          Console.WriteLine(string.Format("{0}: {1}", 
                                          property.Name, 
                                          property.Value));
    }
}

但是我需要的属性总是返回相同的:

打印机状态:0

打印机状态:3

基本上我需要这个来检查打印机是否缺纸。我认为会是什么:打印机状态:4

在 wxp-86 和 w7-64 上测试返回相同的 .Net 4.0

谢谢。

.net 4.0 - C# 打印机属性 WMI

我也遇到了这个问题,没有简单的解决方法。

此问题的原因是 Windows 管理规范 (WMI) 从 spoolsv.exe 进程中检索打印机信息。因此,检索到的信息的可靠性完全取决于打印机驱动程序。您正在查询信息的打印机的驱动程序可能绕过后台处理程序以获取状态,或者它没有向后台处理程序进程报告状态。

Win32_Printer将报告后台处理程序中包含的任何状态。因此,如果后台处理程序报告就绪,则它永远不会接收状态更改的数据因为默认值为就绪Win32_Printer只是将其导出为空闲(打印机状态 = 3 或打印机状态 = 0)。

根据 msdn 的说法,Paper Out=5

using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                string printerName = "PrinterName";
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root''CIMV2", 
                    "SELECT * FROM Win32_Printer "
                     + "WHERE Name LIKE '%{0}'", printerName);); 
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_Printer instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("PrinterStatus: {0}", queryObj["PrinterStatus"]);
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}

这一行:

string query = string.Format("SELECT * from Win32_Printer " 
                            + "WHERE Name LIKE '%{0}'",
                         printerName);

尝试在打印机名称后用%调用它:

string query = string.Format("SELECT * from Win32_Printer " 
                            + "WHERE Name LIKE '%{0}%'",
                         printerName);

打印机名称通常为:"[打印机名称] 在 [端口]上"

此外,您可以检查扩展打印机状态和其他属性;有线打印机可以提供比无线打印机(局域网、WLAN、蓝牙)更多的信息。

https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printer

using System;
using System.Management;
using System.Windows.Forms;
namespace PrinterSet
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            QueryOnWMI();
        }
        private void QueryOnWMI()
        {
            try
            {
                // Common Information Model v2 (namespace)
                string scope = @"root'CIMV2";
                string printerName = printerNameTextBox.Text.Trim();
                //printerName = "%DocuCentre%";
                string query = "SELECT * FROM Win32_Printer";
                if (!string.IsNullOrEmpty(printerName))
                {
                    query += $" WHERE Name Like '%{printerName}%'";
                }
                Console.Clear();
                var searcher = new ManagementObjectSearcher(scope, query);
                var result = searcher.Get();
                if (result == null || result.Count == 0)
                {
                    Console.WriteLine($"Printer '{printerName}' not found");
                }
                var line = new string('-', 40);
                foreach (ManagementObject queryObj in result)
                {
                    Console.WriteLine(line);
                    Console.WriteLine($"Printer : {queryObj["Name"]}");
                    ushort ps = Convert.ToUInt16(queryObj["PrinterStatus"]);
                    var psEnum = (PrinterStatus)ps;
                    Console.WriteLine("PrinterStatus: {0} ({1})", psEnum, ps);
                    ps = Convert.ToUInt16(queryObj["ExtendedPrinterStatus"]);
                    var psExtended = (ExtendedPrinterStatus)ps;
                    Console.WriteLine("Extended Status: {0} ({1})", psExtended, ps);
                    //var papers = (string[])queryObj["PrinterPaperNames"];
                    //foreach (var paper in papers)
                    //{
                    //    Console.WriteLine("Paper Name: {0}", paper);
                    //}
                    Console.WriteLine(line);
                }
            }
            catch (ManagementException emx)
            {
                // TRY => NET STOP SPOOLER
                // Generic failure is thrown 
                MessageBox.Show(this, "Invalid query: " + emx.Message);
            }
        }
        public enum PrinterStatus : UInt16
        {
            Other = 1, Unknown = 2, Idle = 3, Printing= 4, Warmup = 5, StoppedPrinting = 6, Offline = 7, 
        }
        public enum ExtendedPrinterStatus : UInt16
        {
            Other = 1, Unknown = 2, Idle = 3, Printing, WarmingUp, StoppedPrinting, Offline, Paused, Error, 
            Busy, NotAvailable, Waiting, Processing, Initialization, PowerSave, PendingDeletion, IOActive, ManualFeed
        }
        private void button1_Click(object sender, EventArgs e)
        {
            QueryOnWMI();
        }
    }
}

您还可以探索 Windows 后台处理程序 API:https://learn.microsoft.com/en-us/windows-hardware/drivers/print/introduction-to-spooler-components

而这个:窗口打印机driver@stackoverflow

安东尼奥