How do I get the Printer Status when WMI doesn't have it?

Michele Hobson 21 Reputation points
2022-12-06T12:00:52.077+00:00

I've been trying to get the printer status using my .Net desktop application, but it always returns Idle. In addition to using WMIObject, I've tried Microsoft's example of returning the print queue status which doesn't recognize when the printer is unavailable, and I tried using rundll32 printui.dll, PrintUIEntry, which also did not return the needed results.

Does anyone know what Microsoft is using to read the status shown in the first image, and if so, the syntax for using it? Or of any other method of extracting a printer's status that can circumvent the issue shown in the second image?

Thank you in advance

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,422 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 81,721 Reputation points
    2022-12-07T12:15:30.157+00:00

    A test of PKEY_Printer_Status in VB =>

        Dim FOLDERID_PrintersFolder As Guid = New Guid("76FC4E2D-D6AD-4519-A663-37BD56068185")  
        Dim psi As IntPtr = IntPtr.Zero  
        Dim hr As HRESULT = SHGetKnownFolderItem(FOLDERID_PrintersFolder, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, IntPtr.Zero, GetType(IShellItem).GUID, psi)  
        If (hr = HRESULT.S_OK) Then  
            Dim pShellItemFolder As IShellItem = CType(Marshal.GetObjectForIUnknown(psi), IShellItem)  
            Dim BHID_EnumItems As New Guid("94f60519-2850-4924-aa5a-d15e84868039")  
            Dim pEnumItemsPtr As IntPtr = IntPtr.Zero  
            hr = pShellItemFolder.BindToHandler(IntPtr.Zero, BHID_EnumItems, GetType(IEnumShellItems).GUID, pEnumItemsPtr)  
            If (hr = HRESULT.S_OK) Then  
                Dim pEnumShellItems As IEnumShellItems = CType(Marshal.GetObjectForIUnknown(pEnumItemsPtr), IEnumShellItems)  
                Dim nFetched As UInteger = 0  
                Dim pShellItem As IShellItem = Nothing  
                Dim nCpt = 1  
                While ((HRESULT.S_OK = pEnumShellItems.Next(1, pShellItem, nFetched)) AndAlso (nFetched = 1))  
                    Dim sbDisplayName As Text.StringBuilder = New Text.StringBuilder(260)  
                    hr = pShellItem.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, sbDisplayName)  
                    If (hr = HRESULT.S_OK) Then  
                        Console.WriteLine(String.Format("Printer n° {0} : {1}", nCpt.ToString(), sbDisplayName.ToString()))  
                        Dim pShellItem2 As IShellItem2 = DirectCast(pShellItem, IShellItem2)  
                        Dim sModel As String = Nothing  
                        hr = pShellItem2.GetString(PKEY_Printer_Model, sModel)  
                        If (hr = HRESULT.S_OK) Then  
                            Console.WriteLine(String.Format(vbTab + "Model : {0}", sModel))  
                            Dim sStatus As String = Nothing  
                            hr = pShellItem2.GetString(PKEY_Printer_Status, sStatus)  
                            If (hr = HRESULT.S_OK) Then  
                                Console.WriteLine(String.Format(vbTab + "Status : {0}", sStatus))  
                            End If  
                        End If  
                    End If  
                    'Marshal.ReleaseComObject(pShellItem)  
                    nCpt += 1  
                End While  
                Marshal.ReleaseComObject(pShellItem)  
                Marshal.ReleaseComObject(pEnumShellItems)  
            End If  
            Marshal.ReleaseComObject(pShellItemFolder)  
        End If  
    

    with declarations (cannot post here) : IShellItem & IShellItem2


1 additional answer

Sort by: Most helpful
  1. Castorix31 81,721 Reputation points
    2022-12-06T12:06:12.86+00:00

    I had posted some code in this thread : Getting status of printer in VB6 WITHOUT printing a job first

    1 person found this answer helpful.