仅当打印机处于活动状态时使用注册表设置默认打印机 VBA

Using Registry to Set Default Printer VBA ONLY When Printer is Active

我使用 Leith Ross 的 VBA 代码在我的 machine/network 上循环使用打印机,select 与我作为默认打印机传递的参数相匹配的打印机。见下文:

Function FindPrinter(ByVal PrinterName As String) As String

  Dim Arr As Variant
  Dim Device As Variant
  Dim Devices As Variant
  Dim Printer As String
  Dim RegObj As Object
  Dim RegValue As String
  Const HKEY_CURRENT_USER = &H80000001

  Set RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\.\root\default:StdRegProv")
  RegObj.enumvalues HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Devices, Arr

  For Each Device In Devices
    RegObj.getstringvalue HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Device, RegValue
    Printer = Device & " on " & Split(RegValue, ",")(1)
    If InStr(1, Printer, PrinterName, vbTextCompare) > 0 Then
       FindPrinter = Printer
       Exit Function
     End If
  Next


End Function

这会稍微复杂一些,因为 IT 有时会为打印机命名略有不同的名称。尽管如此,我使用的函数还是找到了我正在寻找的打印机并将其设置为默认打印机。

当一些使用此代码的计算机上有重复的 drivers/software 打印机时,真正的问题就来了,其中只有一个在线,而其余的都离线。我通常必须让 IT 人员卸载离线驱动程序,否则此功能有时会抓取离线驱动程序并且代码不起作用。我不必依赖它们来执行此操作,而是有兴趣修改此功能,以便仅在与函数中的 Instr 条件匹配的打印机处于活动状态时,才将活动打印机设置为我将其传递给的任何条件。

VBA、and/or 中是否有任何我可以添加到此代码的内容,以检查符合 Instr 条件的打印机是否确实在线,如果在线,则FindPrinter = PrinterExit Function?我的在线搜索结果并没有真正帮助;几乎所有东西都只是将此功能或其他功能提供给 display/set 默认打印机。

编辑:请注意,并不是真的在寻找讲义答案,但如果您提供确切的操作方法,我将不胜感激。如果您更愿意 link 我找到关于在哪里可以找到 answer/solution 的文档,我将非常乐意进行研究。

因为这将是 link 唯一的答案,我 post 下面的相关文本...


http://www.merrioncomputing.com/Programming/PrintStatus.htm

偷来的

从 Visual Basic 获取所选打印机的状态 打印机对象遗漏了什么

长期以来,在 Visual Basic 中开发完整和专业的应用程序时,打印一直是一个非常有问题的部分。 Visual Basic 4 中引入的新打印机对象在很大程度上解决了这个问题。

然而,这个对象也有缺点。最大的缺点是你无法从你的应用程序中得知打印机是否就绪、忙碌、缺纸等。

幸运的是,有一个 API 调用 GetPrinter,它 returns 提供了大量关于打印机的更多信息。

Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _
       "GetPrinterA" (ByVal hPrinter As Long, _
         ByVal Level As Long, _
         buffer As Long, _
         ByVal pbSize As Long, _
         pbSizeNeeded As Long) As Long

这会获取 hPrinter 中打印机的句柄,并使用来自打印机驱动程序的信息填充提供给它的缓冲区。要从 Printer 对象获取句柄,您需要使用 OpenPrinter API 调用。 一旦完成,必须使用 ClosePrinter API 调用释放此句柄。

Private Type PRINTER_DEFAULTS
  pDatatype As String
  pDevMode As DEVMODE
  DesiredAccess As Long
End Type

Private Declare Function OpenPrinter Lib "winspool.drv" _
    Alias "OpenPrinterA" (ByVal pPrinterName As String, _
    phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long

Private Declare Function ClosePrinter Lib "winspool.drv" _
    (ByVal hPrinter As Long) As Long

您将 Printer.DeviceName 传递给此以获得句柄。

Dim lret As Long
Dim pDef As PRINTER_DEFAULTS

lret = OpenPrinter(Printer.DeviceName, mhPrinter, pDef)

不同的状态

打印机驱动程序可以返回许多标准状态。

Public Enum Printer_Status
   PRINTER_STATUS_READY = &H0
   PRINTER_STATUS_PAUSED = &H1
   PRINTER_STATUS_ERROR = &H2
   PRINTER_STATUS_PENDING_DELETION = &H4
   PRINTER_STATUS_PAPER_JAM = &H8
   PRINTER_STATUS_PAPER_OUT = &H10
   PRINTER_STATUS_MANUAL_FEED = &H20
   PRINTER_STATUS_PAPER_PROBLEM = &H40
   PRINTER_STATUS_OFFLINE = &H80
   PRINTER_STATUS_IO_ACTIVE = &H100
   PRINTER_STATUS_BUSY = &H200
   PRINTER_STATUS_PRINTING = &H400
   PRINTER_STATUS_OUTPUT_BIN_FULL = &H800
   PRINTER_STATUS_NOT_AVAILABLE = &H1000
   PRINTER_STATUS_WAITING = &H2000
   PRINTER_STATUS_PROCESSING = &H4000
   PRINTER_STATUS_INITIALIZING = &H8000
   PRINTER_STATUS_WARMING_UP = &H10000
   PRINTER_STATUS_TONER_LOW = &H20000
   PRINTER_STATUS_NO_TONER = &H40000
   PRINTER_STATUS_PAGE_PUNT = &H80000
   PRINTER_STATUS_USER_INTERVENTION = &H100000
   PRINTER_STATUS_OUT_OF_MEMORY = &H200000
   PRINTER_STATUS_DOOR_OPEN = &H400000
   PRINTER_STATUS_SERVER_UNKNOWN = &H800000
   PRINTER_STATUS_POWER_SAVE = &H1000000
End Enum