如何从Win32_PrintJob的打印作业中获取打印机名称?

时间:2017-01-18 09:34:47

标签: c# printing wmi

我可以使用WMI和Win32_PrintJobManagementEventWatcher获取打印作业信息,但我似乎无法找到打印机名称。我还查看了这个Win32_PrintJob文档,与打印机名称最接近的是DriverName属性,但它是打印机驱动程序名称,而不是控制面板设备中显示的打印机名称。打印机。

因此,如标题所述,如何从Win32_PrintJob的打印作业中获取打印机名称?

这是我到目前为止获得打印作业的部分代码:

public void PrintHelperInstance_OnPrintJobChange(object sender, EventArrivedEventArgs e)
{
    ManagementBaseObject objProps = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;

    string jobName = objProps["Document"].ToString();

    if (jobName == "Test Print Form")
    {
        if (!IsFoundPrintJob)
        {
            IsFoundPrintJob = true;
        }

        CurrentJobStatus = (string)objProps["JobStatus"];

        if (CurrentJobStatus != PreviousJobStatus)
        {
            uint jobId = (uint)objProps["JobId"];
            string jobPrinter = (string)objProps["DriverName"];
            string jobHost = (string)objProps["HostPrintQueue"];
            string jobStatus = (string)objProps["JobStatus"];

            PreviousJobStatus = CurrentJobStatus;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用此代码:

// produce wmi query object
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer);
// produce search object
ManagementObjectSearcher search = new ManagementObjectSearcher(quer);
// retrieve result collection
ManagementObjectCollection restul = search.Get();
// iterate through all printers 
foreach(ManagementObject obj in result)
{
    // now create your temp printer class
    Dictionary<string, object> printerObj = new Dictionary<string, object>();
    if(obj.GetPropertyValue("Local").ToString().Equals("true"))
    {
        printerObj.Add("isLocal", true);
        printerObj.Add("name", obj.GetPropertyValue("name").ToString());
    }
    else 
    {
        printerObj.Add("isLocal", false);
        printerObj.Add("serverName", obj.GetPropertyValue("ServerName").ToString());
        printerObj.Add("shareName", obj.GetPropertyValue("ShareName").ToString());
    }

    // create real printer object
    PrintServer srv = ((bool)printerObj["isLocal")) ? new LocalPrintServer() : new PrintServer((string)printerObj["serverName"]);
    PrintQueue queue = srv.GetPrintQueue(((bool)printerObj["isLocal")) ? (string)printerObj["name"] : (string)printerObj["shareName"];

    foreach(var job in queue.GetPrintJobInfoCollection())
    {
        // check job info and if it matches, return printer name;
    }
}

答案 1 :(得分:0)

尽管我发现标记的答案很有用,但仍应使用一些约定:

  • 使用调用Dispose的方法
  • 合同规定,避免传递空值
  • 在新对象上设置属性的更有效语法
  • 如果可能的话,使用NameOf方法代替字符串

创建的某些对象可以根据您的用途进行扩展:

Namespace PrintQueueTool
    Public Interface IPrintJob
        Property JobId As Integer
        Property JobName As String
        Property JobOwner As String
    End Interface
End Namespace
Imports System.Collections.ObjectModel

Namespace PrintQueueTool
    Public Interface IPrinter
        Property Id As String
        Property IsDefault As Boolean
        Property IsLocal As Boolean
        Property Name As String
        Property ServerName As String
        Property ShareName As String
        Property PrintJobs As ObservableCollection(Of IPrintJob)
    End Interface
End Namespace

对于上述对象,viewmodel如下将打印机加载到其Printer对象集合中:

        Private Sub GetPrinters()

            Dim objScope = New ManagementScope(ManagementPath.DefaultPath)
            objScope.Connect()

            Dim selectQuery As SelectQuery = New SelectQuery With {.QueryString = "Select * from win32_Printer"}
            Using searcher = New ManagementObjectSearcher(objScope, selectQuery)
                Using moCollection = searcher.Get()
                    PrinterCollection = New ObservableCollection(Of IPrinter)
                    For Each mo As ManagementObject In moCollection
                        Dim newPrinter = New Printer(mo)
                        PrinterCollection.Add(newPrinter)
                    Next mo
                End Using
            End Using
        End Sub

打印机对象通过传递的ManagementObject构建其自己的属性和队列

        Public Sub New(managementObject As System.Management.ManagementObject)
         Contracts.Contract.Requires(managementObject IsNot Nothing)
         Id = Guid.NewGuid().ToString()
            Name = managementObject(NameOf(Name))
            IsDefault = CBool(managementObject("Default"))
            IsLocal = CBool(managementObject("Local"))
            Using srv As PrintServer = If((CBool(managementObject("Local"))), New LocalPrintServer(), New PrintServer(CStr(managementObject("serverName"))))
                Using queue As PrintQueue = srv.GetPrintQueue(If((CBool(managementObject("Local"))), CStr(managementObject(NameOf(Name))), CStr(managementObject("shareName"))))
                    PrintJobs = New ObservableCollection(Of IPrintJob)
                    Using jobs = queue.GetPrintJobInfoCollection()
                        For Each job In jobs
                            Dim printJob = New PrintJob With
                            {
                                .JobId = job.JobIdentifier,
                                .JobName = job.JobName,
                                .JobOwner = job.Submitter
                            }
                        Next
                    End Using
                End Using
            End Using
        End Sub