Introduction
This article presents a simplified approach of controlling print jobs using WMI. To know more about WMI, please visit MSDN.
Why WMI? Because it provides a simplified approach and avoids making API calls within our C# code. WMI comes as default for Windows XP and Windows 2000. For Windows 95/98, we need to download WMI Core 1.5 and install it: WMI Core 1.5.
The Approach
First, let's see how to get the list of printers.
public
static StringCollection GetPrintersCollection()
{
StringCollection printerNameCollection = new StringCollection();
string searchQuery = "SELECT * FROM Win32_Printer";
ManagementObjectSearcher searchPrinters =
new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection printerCollection = searchPrinters.Get();
foreach(ManagementObject printer in printerCollection)
{
printerNameCollection.Add(printer.Properties["Name"].Value.ToString());
}
return printerNameCollection;
}
The above method returns the list of printers configured in the local machine. The printer ManagementObject exposes many useful properties. Using the PaperSizesSupported property, we can get the list of paper sizes supported by that particular printer. To view information about Win32_Printer, please refer MSDN.
Using this printer name, we can fetch the print job collection by using the following method:
Collapse
public
static StringCollection GetPrintJobsCollection(string printerName)
{
StringCollection printJobCollection = new StringCollection();
string searchQuery = "SELECT * FROM Win32_PrintJob";
ManagementObjectSearcher searchPrintJobs =
new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
foreach(ManagementObject prntJob in prntJobCollection)
{
System.String jobName = prntJob.Properties["Name"].Value.ToString();
char[] splitArr = newchar[1];
splitArr[0] = Convert.ToChar(",");
string prnterName = jobName.Split(splitArr)[0];
string documentName = prntJob.Properties["Document"].Value.ToString();
if(String.Compare(prnterName, printerName, true) == 0)
{
printJobCollection.Add(documentName);
}
}
return printJobCollection;
}
The query "SELECT * FROM Win32_PrintJob" can also be used as "SELECT * FROM Win32_PrintJob WHERE Name like '"+ printerName.Replace("\", "\\") +"%'". But the query with WHICH attribute caused problems in my system which was running Windows 2000, but ran smooth in Windows XP machines. So currently, I am making a loop through all the print jobs and identify print jobs for that particular printer.
Now, let's see how to manage these print jobs. The print console provided by Windows allows us to Pause, Resume and Cancel print jobs. It also allows to set priority for a print job. Using WMI, we can perform Pause, Resume and Cancel, but it doesn't provide any method for changing the priority level.
The following code depicts how to pause a print job:
Collapse
public
static
bool PausePrintJob(string printerName, int printJobID)
{
bool isActionPerformed = false;
string searchQuery = "SELECT * FROM Win32_PrintJob";
ManagementObjectSearcher searchPrintJobs =
new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
foreach(ManagementObject prntJob in prntJobCollection)
{
System.String jobName = prntJob.Properties["Name"].Value.ToString();
char[] splitArr = newchar[1];
splitArr[0] = Convert.ToChar(",");
string prnterName = jobName.Split(splitArr)[0];
int prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]);
string documentName = prntJob.Properties["Document"].Value.ToString();
if(String.Compare(prnterName, printerName, true) == 0)
{
if(prntJobID == printJobID)
{
prntJob.InvokeMethod("Pause", null);
isActionPerformed = true;
break;
}
}
}
return isActionPerformed;
}
By invoking the Pause method, we can pause the print job. Similar approach is required for resuming the print job. Just we need to invoke the Resume method.
prntJob.InvokeMethod("Resume", null);
Win32_PrintJob WMI_CLASS provides methods to pause and resume a print job. But it doesn't provide any method for canceling the print job. To cancel the print job, you need to just delete the management object.
Collapse
public
static
bool CancelPrintJob(string printerName, int printJobID)
{
bool isActionPerformed = false;
string searchQuery = "SELECT * FROM Win32_PrintJob";
ManagementObjectSearcher searchPrintJobs =
new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
foreach(ManagementObject prntJob in prntJobCollection)
{
System.String jobName = prntJob.Properties["Name"].Value.ToString();
char[] splitArr = newchar[1];
splitArr[0] = Convert.ToChar(",");
string prnterName = jobName.Split(splitArr)[0];
int prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]);
string documentName = prntJob.Properties["Document"].Value.ToString();
if(String.Compare(prnterName, printerName, true) == 0)
{
if(prntJobID == printJobID)
{
prntJob.Delete();
isActionPerformed = true;
break;
}
}
}
return isActionPerformed;
}
That's it.
mubbsher
|
Click here to view mubbsher's online profile.
|