Reputation: 571
I am able to get print job informations from Win32_PrintJob
by using WMI and ManagementEventWatcher
but I cannot seem to find the printer name. I also looked to this Win32_PrintJob documentation and the closest thing to printer name is DriverName
property, but it is the printer driver name, not the printer name as displayed in the Control Panel's Devices and Printers.
So, as stated in the title, how can I get the printer name from print job from Win32_PrintJob
?
This is my partial codes so far to get the print job:
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;
}
}
}
Upvotes: 1
Views: 2317
Reputation: 5930
You can use this code :
// produce wmi query object
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer");
// produce search object
ManagementObjectSearcher search = new ManagementObjectSearcher(query);
// retrieve result collection
ManagementObjectCollection result = 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;
}
}
Upvotes: 2
Reputation: 483
Although I found the marked answer useful, there are some conventions that should be used:
There are certain objects created that can be extended for your purposes:
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
With the above objects, the viewmodel loads the printers into its collection of Printer objects as follows:
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
The printer object builds its own properties and queue from the ManagementObject it is passed
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
Upvotes: 0