Shane Russell
asked on
WMI, Printer c# 2005 express ?
ok Found this article on codeproject.com and this is the first time I have used c# and I dont see any download to the source code to a working example and am having a hard time trying to use wmi within any language in 2005 so if someone could help me get this example on code project working that would be great.
Preferably with a cancel button and a cancel all button so that I can cancel individual print jobs or all the print jobs in the printer's que for a remote machine.
Here is the code project article :
http://www.codeproject.com/csharp/prntjobcontrollerusingwmi.asp
Preferably with a cancel button and a cancel all button so that I can cancel individual print jobs or all the print jobs in the printer's que for a remote machine.
Here is the code project article :
http://www.codeproject.com/csharp/prntjobcontrollerusingwmi.asp
WMI requires that you add a "Reference" to your project before it will work.
This is typically done from the Solution Explorer (usually in the upper right-hand corner of the Visual Studio's IDE. Right click on the "References" item and select "Add Reference". A dialog box will appear... scroll about 3/4 of the way down, and select "System.Management".
This is typically done from the Solution Explorer (usually in the upper right-hand corner of the Visual Studio's IDE. Right click on the "References" item and select "Add Reference". A dialog box will appear... scroll about 3/4 of the way down, and select "System.Management".
ASKER
TheLearnedOne :
I need this in rich dummy terms with regards to where to put all this code as well as how to cancel individual jobs and or cancel all the print jobs.
graye :
I have already added the system management reference and that didnt help any as I still got errors as I have no clue where to copy and paste that code to because whenever I copy and paste the code that is given in that example from code project it just flags up errors.
Any chance you could get the example in the code project working and uploaded to some webspace in a zip file ( Because if the reply regarding connecting to a remote machine on code project is correct here :
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = textUserID.Text;
co.Password = textPassword.Text;
//Point to machine
System.Management.Manageme ntScope ms = new System.Management.
ManagementScope("\\\\" + stringHostName + "\\root\\cimv2", co);
Then connecting to a remote machine shouldn't be an issue ( As long as I know how to cancel invidual jobs as well as all the jobs ( obviously in 2 seperate buttons ) Then I will be fine.
Thanks for the help
I need this in rich dummy terms with regards to where to put all this code as well as how to cancel individual jobs and or cancel all the print jobs.
graye :
I have already added the system management reference and that didnt help any as I still got errors as I have no clue where to copy and paste that code to because whenever I copy and paste the code that is given in that example from code project it just flags up errors.
Any chance you could get the example in the code project working and uploaded to some webspace in a zip file ( Because if the reply regarding connecting to a remote machine on code project is correct here :
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = textUserID.Text;
co.Password = textPassword.Text;
//Point to machine
System.Management.Manageme
ManagementScope("\\\\" + stringHostName + "\\root\\cimv2", co);
Then connecting to a remote machine shouldn't be an issue ( As long as I know how to cancel invidual jobs as well as all the jobs ( obviously in 2 seperate buttons ) Then I will be fine.
Thanks for the help
Step 4: Cancel individual jobs.
The Win32_Printer class has CancelAllJobs. The Win32_PrintJob has a Pause and a Resume method. Neither of these will do what you need. To cancel the print job, you need to just delete the management object.
job.Document.Delete();
External reference:
A simple approach for controlling print jobs using WMI
http://www.codeproject.com/csharp/prntjobcontrollerusingwmi.asp
Bob
The Win32_Printer class has CancelAllJobs. The Win32_PrintJob has a Pause and a Resume method. Neither of these will do what you need. To cancel the print job, you need to just delete the management object.
job.Document.Delete();
External reference:
A simple approach for controlling print jobs using WMI
http://www.codeproject.com/csharp/prntjobcontrollerusingwmi.asp
Bob
ASKER
so remind me, where does all the code go ? Do I need to create a new class to put your public class into or can I just copy and paste that into the same code window as the rest of the code or what steps do I need to take exactly ?
Step 5: Implementation
1) Add a new class, called Win32_PrintJob, and paste the code from the class definition
2) The Win32_PrintJob.GetList returns an array of Win32_PrintJob elements, which contain the properties for each of the print job objects
3) Add a new property to the class:
public ManagementObject PrintJob;
4) Add this line to GetList:
job.PrintJob = entryCurrent;
5) Add a method to Win32_PrintJob:
public static DeleteJob()
{
PrintJob.InvokeMethod("Del ete", null);
}
6) Add your code to set the management scope for the remote machine
7) Get all the print jobs:
Win32_PrintJob[] list = Win32_PrintJob.GetList();
8) Cancel the job that you need
HTH
Bob
1) Add a new class, called Win32_PrintJob, and paste the code from the class definition
2) The Win32_PrintJob.GetList returns an array of Win32_PrintJob elements, which contain the properties for each of the print job objects
3) Add a new property to the class:
public ManagementObject PrintJob;
4) Add this line to GetList:
job.PrintJob = entryCurrent;
5) Add a method to Win32_PrintJob:
public static DeleteJob()
{
PrintJob.InvokeMethod("Del
}
6) Add your code to set the management scope for the remote machine
7) Get all the print jobs:
Win32_PrintJob[] list = Win32_PrintJob.GetList();
8) Cancel the job that you need
HTH
Bob
ASKER
ok here is my code so far :
'-------------------------
using System;
using System.Collections.Generic ;
using System.Text;
using System;
using System.Management;
namespace PrintJob
{
class Win32_PrintJob
{
public ManagementObject PrintJob;
public string DataType;
public string Description;
public string Document;
public string DriverName;
public DateTime ElapsedTime;
public string HostPrintQueue;
public DateTime InstallDate;
public int JobId;
public string JobStatus;
public string Notify;
public string Owner;
public int PagesPrinted;
public string Parameters;
public string PrintProcessor;
public int Priority;
public int Size;
public System.DateTime StartTime;
public string Status;
public int StatusMask;
public DateTime TimeSubmitted;
public int TotalPages;
public DateTime UntilTime;
public static Win32_PrintJob[] GetList()
{
string query = "Select * From Win32_PrintJob";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q uery);
ManagementObjectCollection results = searcher.Get();
Win32_PrintJob[] listPrintJobs = new Win32_PrintJob[results.Cou nt - 1];
int index = 0;
foreach (ManagementObject entryCurrent in results)
{
Win32_PrintJob job = new Win32_PrintJob();
job.PrintJob = entryCurrent;
job.DataType = (string)entryCurrent["Data Type"];
job.Description = (string)entryCurrent["Desc ription"];
job.Document = (string)entryCurrent["Docu ment"];
job.DriverName = (string)entryCurrent["Driv erName"];
job.ElapsedTime = ConvertFileTime((string)en tryCurrent ["ElapsedT ime"]);
job.HostPrintQueue = (string)entryCurrent["Host PrintQueue "];
job.InstallDate = ConvertFileTime((string)en tryCurrent ["InstallD ate"]);
job.JobId = Convert.ToInt32(entryCurre nt["JobId" ]);
job.JobStatus = (string)entryCurrent["JobS tatus"];
job.Notify = (string)entryCurrent["Noti fy"];
job.Owner = (string)entryCurrent["Owne r"];
job.PagesPrinted = Convert.ToInt32(entryCurre nt["PagesP rinted"]);
job.Parameters = (string)entryCurrent["Para meters"];
job.PrintProcessor = (string)entryCurrent["Prin tProcessor "];
job.Priority = Convert.ToInt32(entryCurre nt["Priori ty"]);
job.Size = Convert.ToInt32(entryCurre nt["Size"] );
job.StartTime = ConvertFileTime((string)en tryCurrent ["StartTim e"]);
job.Status = (string)entryCurrent["Stat us"];
job.StatusMask = Convert.ToInt32(entryCurre nt["Status Mask"]);
job.TimeSubmitted = ConvertFileTime((string)en tryCurrent ["TimeSubm itted"]);
job.TotalPages = Convert.ToInt32(entryCurre nt["TotalP ages"]);
job.UntilTime = ConvertFileTime((string)en tryCurrent ["UntilTim e"]);
listPrintJobs[index] = job;
index++;
}
return listPrintJobs;
}
private static DateTime ConvertFileTime(string time)
{
if (time != null)
{
const string FILE_TIME_MASK = "yyyyMMddHHmmss";
time = time.Substring(0, time.IndexOf("."));
return DateTime.ParseExact(time, FILE_TIME_MASK, null);
}
return DateTime.MinValue;
}
}
}
'------------------------- --
Im not sure where to put the code for step 5 or 7 and how do I link this class to the actual user form so that I can see this working ?
'-------------------------
using System;
using System.Collections.Generic
using System.Text;
using System;
using System.Management;
namespace PrintJob
{
class Win32_PrintJob
{
public ManagementObject PrintJob;
public string DataType;
public string Description;
public string Document;
public string DriverName;
public DateTime ElapsedTime;
public string HostPrintQueue;
public DateTime InstallDate;
public int JobId;
public string JobStatus;
public string Notify;
public string Owner;
public int PagesPrinted;
public string Parameters;
public string PrintProcessor;
public int Priority;
public int Size;
public System.DateTime StartTime;
public string Status;
public int StatusMask;
public DateTime TimeSubmitted;
public int TotalPages;
public DateTime UntilTime;
public static Win32_PrintJob[] GetList()
{
string query = "Select * From Win32_PrintJob";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q
ManagementObjectCollection
Win32_PrintJob[] listPrintJobs = new Win32_PrintJob[results.Cou
int index = 0;
foreach (ManagementObject entryCurrent in results)
{
Win32_PrintJob job = new Win32_PrintJob();
job.PrintJob = entryCurrent;
job.DataType = (string)entryCurrent["Data
job.Description = (string)entryCurrent["Desc
job.Document = (string)entryCurrent["Docu
job.DriverName = (string)entryCurrent["Driv
job.ElapsedTime = ConvertFileTime((string)en
job.HostPrintQueue = (string)entryCurrent["Host
job.InstallDate = ConvertFileTime((string)en
job.JobId = Convert.ToInt32(entryCurre
job.JobStatus = (string)entryCurrent["JobS
job.Notify = (string)entryCurrent["Noti
job.Owner = (string)entryCurrent["Owne
job.PagesPrinted = Convert.ToInt32(entryCurre
job.Parameters = (string)entryCurrent["Para
job.PrintProcessor = (string)entryCurrent["Prin
job.Priority = Convert.ToInt32(entryCurre
job.Size = Convert.ToInt32(entryCurre
job.StartTime = ConvertFileTime((string)en
job.Status = (string)entryCurrent["Stat
job.StatusMask = Convert.ToInt32(entryCurre
job.TimeSubmitted = ConvertFileTime((string)en
job.TotalPages = Convert.ToInt32(entryCurre
job.UntilTime = ConvertFileTime((string)en
listPrintJobs[index] = job;
index++;
}
return listPrintJobs;
}
private static DateTime ConvertFileTime(string time)
{
if (time != null)
{
const string FILE_TIME_MASK = "yyyyMMddHHmmss";
time = time.Substring(0, time.IndexOf("."));
return DateTime.ParseExact(time, FILE_TIME_MASK, null);
}
return DateTime.MinValue;
}
}
}
'-------------------------
Im not sure where to put the code for step 5 or 7 and how do I link this class to the actual user form so that I can see this working ?
Do you have a main GUI form?
Bob
Bob
ASKER
Yes I clicked in the toolbar on insert and selected add windows form and it inserted a form.
ASKER
Just looking at the coding side with regards to connecting to the remote machine ( I dont understand where to put the following code )
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = textUserID.Text;
co.Password = textPassword.Text;
//Point to machine
System.Management.Manageme ntScope ms = new System.Management.
ManagementScope("\\\\" + stringHostName + "\\root\\cimv2", co);
Does it go in place of this code :
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q uery);
ManagementObjectCollection results = searcher.Get();
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = textUserID.Text;
co.Password = textPassword.Text;
//Point to machine
System.Management.Manageme
ManagementScope("\\\\" + stringHostName + "\\root\\cimv2", co);
Does it go in place of this code :
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q
ManagementObjectCollection
1) Add the scope to the searcher:
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q uery);
searcher.Scope = ms;
2) Add a list box to display the print job descriptions
3) Add a button to delete the job
4) Get a reference to the right Win32_PrintJob object, and call the DeleteJob method.
Bob
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q
searcher.Scope = ms;
2) Add a list box to display the print job descriptions
3) Add a button to delete the job
4) Get a reference to the right Win32_PrintJob object, and call the DeleteJob method.
Bob
ASKER
ok uploaded it to here :
http://www.badongo.com/file/1049914
Not sure how Im supposed to add a button to a delete job and the other steps just went over my head :-S
http://www.badongo.com/file/1049914
Not sure how Im supposed to add a button to a delete job and the other steps just went over my head :-S
ASKER
1 --> I can leave for now and just do it for the local machine and can work on the remote machine part later on.
2 --> Done that already when I added the form as I added a button called cmdPrinter with the caption set to Printer ( which in c sharp is called text obviously )
3 --> Im assuming you mean just adding a button to the form ( Cos thats all Ive done ) and not sure what else to do or what to put in the button or w/e
4 --> How can I tell If I have the right reference to the Win32_PrintJob object and how can I call the DeleteJob Method as that is what I was stuck on ( remember steps 5 and 7 ) with regards to not knowing where to put the code for that.
When I know where to put the code for that then I am assuming its just a case of doing a
Call FunctionName()
Inside of the button ?
2 --> Done that already when I added the form as I added a button called cmdPrinter with the caption set to Printer ( which in c sharp is called text obviously )
3 --> Im assuming you mean just adding a button to the form ( Cos thats all Ive done ) and not sure what else to do or what to put in the button or w/e
4 --> How can I tell If I have the right reference to the Win32_PrintJob object and how can I call the DeleteJob Method as that is what I was stuck on ( remember steps 5 and 7 ) with regards to not knowing where to put the code for that.
When I know where to put the code for that then I am assuming its just a case of doing a
Call FunctionName()
Inside of the button ?
ASKER
you still there or did you give up ?
Man, do you think I live next to my computer, or am I allowed to have a life away from it?
1) If you have an array of objects and a 1-to-1 correspondence with a ListBox, you can get the SelectedIndex, and get the right object from the array
2) Adding a button to a form is a fairly basic operation, and I hope that you are not asking me how to do that.
3) This isn't Visual Basic, so leave off the Call, and just use the function name:
Win32_PrintJob job = jobList[this.ListBox1.Sele ctedIndex] ;
job.DeleteJob();
Bob
1) If you have an array of objects and a 1-to-1 correspondence with a ListBox, you can get the SelectedIndex, and get the right object from the array
2) Adding a button to a form is a fairly basic operation, and I hope that you are not asking me how to do that.
3) This isn't Visual Basic, so leave off the Call, and just use the function name:
Win32_PrintJob job = jobList[this.ListBox1.Sele
job.DeleteJob();
Bob
ASKER
I wasnt trying to say you live next to your computer or anything like that just before you were replying swiftly and then all of a sudden no reply. Sorry about that.
Just about to head off to work so I will give this a try this afternoon when I get back :)
I mis read what you said earlier but hopefully I can get this to work later on.
Just about to head off to work so I will give this a try this afternoon when I get back :)
I mis read what you said earlier but hopefully I can get this to work later on.
ASKER
Is there any chance yourself or someone else could put it all together for me because I have left out the job.deletejob() and just tried to do it for the local machine and now I am even getting errors on this chunk of code
private static DateTime ConvertFileTime(string time)
{
if (time != null)
{
const string FILE_TIME_MASK = "yyyyMMddHHmmss";
time = time.Substring(0, time.IndexOf("."));
return DateTime.ParseExact(time, FILE_TIME_MASK, null);
}
return DateTime.MinValue;
}
It said something about it not being compatable with the gregorian calendar or something about a string or something along those lines.
As per my question this is the first time I have used c# and I am just getting frustrated trying to add in all these niggly little bits left right and centre when I have absolutly no clue where I am supposed to put them exactly.
Is it asking too much for an example that is something like :
put this code into a class called Win32_PrintJob
'whatever the code is
Call it like so from a command button in a form like so :
' code to add the print jobs into a list view and have either a button or a context menu which when the job or jobs are selected you either click cancel all or cancel job to cancel a print job or all of the print jobs.
private static DateTime ConvertFileTime(string time)
{
if (time != null)
{
const string FILE_TIME_MASK = "yyyyMMddHHmmss";
time = time.Substring(0, time.IndexOf("."));
return DateTime.ParseExact(time, FILE_TIME_MASK, null);
}
return DateTime.MinValue;
}
It said something about it not being compatable with the gregorian calendar or something about a string or something along those lines.
As per my question this is the first time I have used c# and I am just getting frustrated trying to add in all these niggly little bits left right and centre when I have absolutly no clue where I am supposed to put them exactly.
Is it asking too much for an example that is something like :
put this code into a class called Win32_PrintJob
'whatever the code is
Call it like so from a command button in a form like so :
' code to add the print jobs into a list view and have either a button or a context menu which when the job or jobs are selected you either click cancel all or cancel job to cancel a print job or all of the print jobs.
You are making me work very hard for my money--oh, wait, I do this for free*BIG GRIN*
Bob
Bob
How would you do this in VB6?
Bob
Bob
ASKER
I wouldn't I was gonna do this in vb 2005 express. I just wanted to give it a go in c# as I have never used c# before.
Any chance you could get an example working for the local machine or at least add in the relevant parts of code into the class and then just give me the code I need to enumerate a listview which would be called from a button or in the form somewhere so that it just fills the list view with the print jobs.
Other then that I have another question open in the vb.net TA so if neither of the above is feasable then possibly help me with the cancelling the print jobs in vb.net 2005 express because I am further ahead with using vb.net with regards to at least having a listview that returns the print jobs in all the printers ( which I can alter to specific printers by using the where clause ie where name = 'printername'
I mean at the end of the day I just want a utility that will allow me to select a printer and either cancel a print job or purge all the print jobs for that printer.
Any chance you could get an example working for the local machine or at least add in the relevant parts of code into the class and then just give me the code I need to enumerate a listview which would be called from a button or in the form somewhere so that it just fills the list view with the print jobs.
Other then that I have another question open in the vb.net TA so if neither of the above is feasable then possibly help me with the cancelling the print jobs in vb.net 2005 express because I am further ahead with using vb.net with regards to at least having a listview that returns the print jobs in all the printers ( which I can alter to specific printers by using the where clause ie where name = 'printername'
I mean at the end of the day I just want a utility that will allow me to select a printer and either cancel a print job or purge all the print jobs for that printer.
I only asked about VB6, because I see where you are involved in that, and I wanted to give you a jumping off point, since C# is not significantly different. I was kinda hopin' that I wouldn't have to do the whole thing for you as I am working on my own problems. Teach someone to fish, and all that ;)
Bob
Bob
ASKER
I've used wmi in vbscript and vb 6 but I havent done classes so that is where I am struggling at least afaik.
To be honest I would be happy just to see this class working and enumerating the print jobs into a listbox at this point.
@ Teach someone to fish, and all that ;)
Are you sure you didn't trip over the fishing line cos I can feel a hook through my finger lol
To be honest I would be happy just to see this class working and enumerating the print jobs into a listbox at this point.
@ Teach someone to fish, and all that ;)
Are you sure you didn't trip over the fishing line cos I can feel a hook through my finger lol
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Its not letting me logon to that ee stuff site, saying my logon credentials are wrong ( which I know isnt true ). email me it ( email is in profile - the yahoo one )
ASKER
that example partialy works but when I click on delete print job it duplicates the other print job and then i click on delete on the duplicated print job and I get an array out of bounds error ( As I have 2 printers installed ) and it is saying that the printer que is for \\nameofmachine ( which is fair enough ) but it doesnt display which printer it is going to ie \\machinename\\printername
anway im off out and if you cant help me with being too busy or w/e thats fine and I will award you points as you have been helpful
anway im off out and if you cant help me with being too busy or w/e thats fine and I will award you points as you have been helpful
1) I don't have 2 printers to debug this one
2) The Owner property might be a link to the machine, but I am not sure
Bob
2) The Owner property might be a link to the machine, but I am not sure
Bob
ASKER
I just installed some fake printers as I want to be able to do this for multiple printers ( If you would prefer I will ask about the bugs in a seperate question )
Nah, we can deal with here. I will try to add some printers, and print to them.
Bob
Bob
ASKER
much appriecated :) thx !! :)
You need to clear the ListView items collection.
Bob
Bob
using System;
using System.Management;
public class Win32_PrintJob
{
public string DataType;
public string Description;
public string Document;
public string DriverName;
public DateTime ElapsedTime;
public string HostPrintQueue;
public DateTime InstallDate;
public int JobId;
public string JobStatus;
public string Notify;
public string Owner;
public int PagesPrinted;
public string Parameters;
public string PrintProcessor;
public int Priority;
public int Size;
public System.DateTime StartTime;
public string Status;
public int StatusMask;
public DateTime TimeSubmitted;
public int TotalPages;
public DateTime UntilTime;
public static Win32_PrintJob[] GetList()
{
string query = "Select * From Win32_PrintJob";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(q
ManagementObjectCollection
Win32_PrintJob[] listPrintJobs = new Win32_PrintJob[results.Cou
int index = 0;
foreach (ManagementObject entryCurrent in results)
{
Win32_PrintJob job = new Win32_PrintJob();
job.DataType = (string)entryCurrent["Data
job.Description = (string)entryCurrent["Desc
job.Document = (string)entryCurrent["Docu
job.DriverName = (string)entryCurrent["Driv
job.ElapsedTime = ConvertFileTime((string)en
job.HostPrintQueue = (string)entryCurrent["Host
job.InstallDate = ConvertFileTime((string)en
job.JobId = Convert.ToInt32(entryCurre
job.JobStatus = (string)entryCurrent["JobS
job.Notify = (string)entryCurrent["Noti
job.Owner = (string)entryCurrent["Owne
job.PagesPrinted = Convert.ToInt32(entryCurre
job.Parameters = (string)entryCurrent["Para
job.PrintProcessor = (string)entryCurrent["Prin
job.Priority = Convert.ToInt32(entryCurre
job.Size = Convert.ToInt32(entryCurre
job.StartTime = ConvertFileTime((string)en
job.Status = (string)entryCurrent["Stat
job.StatusMask = Convert.ToInt32(entryCurre
job.TimeSubmitted = ConvertFileTime((string)en
job.TotalPages = Convert.ToInt32(entryCurre
job.UntilTime = ConvertFileTime((string)en
listPrintJobs[index] = job;
index++;
}
return listPrintJobs;
}
private static DateTime ConvertFileTime(string time)
{
if (time != null)
{
const string FILE_TIME_MASK = "yyyyMMddHHmmss";
time = time.Substring(0, time.IndexOf("."));
return DateTime.ParseExact(time, FILE_TIME_MASK, null);
}
return DateTime.MinValue;
}
}
Step 2: Get a list of print jobs
Call the static GetList and get back and array of Win32_PrintJob objects.
Step 3: Get this from a remote machine
To follow.
Bob