1

你好我有这个代码来检索打印机属性:

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

基本上我需要这个来检查打印机是否缺纸。我认为是:PrinterState:4

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

谢谢你。

4

4 回答 4

3

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

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

Win32_Printer将报告假脱机程序中包含的任何状态。因此,如果假脱机程序报告Ready,则它永远不会收到状态更改的数据,因为默认值为ReadyWin32_Printer只是将其导出为空闲(PrinterStatus = 3 或 PrinterState = 0)。

于 2013-08-13T16:49:39.913 回答
1

根据msdnPaper 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);
            }
        }
    }
}
于 2013-01-22T10:29:20.153 回答
0

这一行:

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

通常打印机名称是:“[printername] On [port]”

于 2013-01-22T10:15:57.627 回答
0

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

https://docs.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 spooler API: https ://docs.microsoft.com/en-us/windows-hardware/drivers/print/introduction-to-spooler-components

还有这个: windows-printer-driver@stackoverflow

安东尼奥

于 2020-09-01T02:55:05.347 回答