471,624 Members | 1,954 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,624 software developers and data experts.

Monitoring printer-spoolers using WMI

Hi folks,

during printing, I'm constantly checking the printer-spooler to monitor
whether a document has showed up in a printer's spooler and - after it has
- whether the print-job has been finished.
I'm using the following code for that:

--- 8< ---
Imports System.Management

Public Class CPrinterQueue
Public Shared Function JobCount(ByVal strPrinterName As String) As Integer
Dim strQuery As String = "SELECT * FROM Win32_PrintJob " & _
"WHERE DriverName = '" & strPrinterName.Replace("'", "''") & "'"
Dim JobQuery As New ManagementObjectSearcher(strQuery)
Dim Jobs As ManagementObjectCollection = JobQuery.Get()

Try
Return Jobs.Count
Catch ex As Exception
Return -1
Finally
Jobs.Dispose()
JobQuery.Dispose()
End Try
End Function
end class
--- 8< ---

As long as I'm only using one printer, everything's fine. But after a set
of documents has been printed, a receipt will be printed to a different
printer. As soon as I use the above class/function with the second printer,
it will return a wrong number of jobs upon first call and the code will
just stop running (at "Return Jobs.Count") afterwards.
If I comment out one of the usages (that is, I'm only monitoring one
printer), everything will be fine.

Any pointers?

Thanks!

Cheers,
Olaf
Nov 21 '05 #1
3 4998
I'd be inclined to throw some Console.Writeline's into the JobCount method.

I suspect that you might be getting some collisions between you usages.
E.g., 2nd usage hitting the JobQuery.Get() before the first usage has
finished returning Jobs.Count.

Another point could be in the Finally clause. I have never fully understood
how one can do what you have done in the Try clause and disposed of the
source object in the Finally clause and still have the correct value
returned. Sure, I have never seen it fail yet, but I don't entirely trust it
(because I don't fully understand it).

I wonder what would happen if you assigned Jobs.Count to a local integer and
returned that instead.

Just because I'm paranoid, it doesn't mean they're not out to get me.
"Olaf Rabbachin" <Ol*********@IntuiDev.com> wrote in message
news:ej**************@TK2MSFTNGP12.phx.gbl...
Hi folks,

during printing, I'm constantly checking the printer-spooler to monitor
whether a document has showed up in a printer's spooler and - after it has
- whether the print-job has been finished.
I'm using the following code for that:

--- 8< ---
Imports System.Management

Public Class CPrinterQueue
Public Shared Function JobCount(ByVal strPrinterName As String) As Integer
Dim strQuery As String = "SELECT * FROM Win32_PrintJob " & _
"WHERE DriverName = '" & strPrinterName.Replace("'", "''") & "'"
Dim JobQuery As New ManagementObjectSearcher(strQuery)
Dim Jobs As ManagementObjectCollection = JobQuery.Get()

Try
Return Jobs.Count
Catch ex As Exception
Return -1
Finally
Jobs.Dispose()
JobQuery.Dispose()
End Try
End Function
end class
--- 8< ---

As long as I'm only using one printer, everything's fine. But after a set
of documents has been printed, a receipt will be printed to a different
printer. As soon as I use the above class/function with the second
printer,
it will return a wrong number of jobs upon first call and the code will
just stop running (at "Return Jobs.Count") afterwards.
If I comment out one of the usages (that is, I'm only monitoring one
printer), everything will be fine.

Any pointers?

Thanks!

Cheers,
Olaf

Nov 21 '05 #2
Hi,

Stephany Young wrote:
I'd be inclined to throw some Console.Writeline's into the JobCount method.
I did that, but it didn't help.
I suspect that you might be getting some collisions between you usages.
E.g., 2nd usage hitting the JobQuery.Get() before the first usage has
finished returning Jobs.Count.
The class I quoted was the simplest I had. I also tried a couple of other
approaches, one i.e. simply having the calling thread sleep for half a
second. Doing so showed each WMI-thread was finished before the next one
was created.
Another point could be in the Finally clause. I have never fully understood
how one can do what you have done in the Try clause and disposed of the
source object in the Finally clause and still have the correct value
returned. Sure, I have never seen it fail yet, but I don't entirely trust it
(because I don't fully understand it).
That's because I'd like to make sure that all objects are disposed of when
exiting the function. How else could you achieve that if not in the
Finally-clause?
I wonder what would happen if you assigned Jobs.Count to a local integer and
returned that instead.


Tried that as well - no change.

Anyway, I found out something else - it seems to be really related to the
printer that I'm not receiving any spooler-related stuff - with some it'll
work and with others it won't. Is there different approaches for different
printers? I don't really see a difference there ... :-(

Cheers,
Olaf
Nov 21 '05 #3
Hi,

Olaf Rabbachin wrote:
Anyway, I found out something else - it seems to be really related to the
printer that I'm not receiving any spooler-related stuff - with some it'll
work and with others it won't. Is there different approaches for different
printers? I don't really see a difference there ... :-(


geez, got it. I was dumb enough to think that the contents of <DriverName>
would always be the printer's name.
So much for trying things out and thinking they'd be right - I tried 4
printers and their <DriverName> always showed the printers' names, but the
one I experienced the problems with was one that had a non-standard driver
which was named differently. Nice that, while testing, I constantly
switched the printers being checked and thus ended up thinking that it was
a matter of two printers in a row being used.

Anyway - instead, I am now using the <Name> item (seems to include the same
information as the <Caption> and <Description> items). Too bad that
property isn't limited to the name (as would've been expected and which was
the reason why I chose to use <DriverName> in the first place) - it
contains a suffix in the form of ", [ID]" where [ID] is the job's ID (also
available via the <JobID>-item). I have no idea as to why it is being
appended - sure doesn't make a whole lot of sense (a bug maybe?).

I'm currently cutting off anything after the last "," which will leave me
with the printer's name.
Also I have to browse all jobs of all printers as the WMI-query doesn't
seem to know LIKE-statements as in regular SQL.

So, unless there's a way (I sure don't know one) to retrieve a printer's
driver-name by the printer's name I'll have to stick with that.

Cheers,
Olaf
Nov 21 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Sven Dzepina | last post: by
2 posts views Thread by Patrick Herb | last post: by
reply views Thread by Dan | last post: by
4 posts views Thread by johnm | last post: by
4 posts views Thread by sengkok | last post: by
1 post views Thread by Karthic | last post: by
1 post views Thread by =?Utf-8?B?UGxheWE=?= | last post: by
1 post views Thread by Tomka | last post: by
1 post views Thread by XIAOLAOHU | last post: by
1 post views Thread by ZEDKYRIE | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.