无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 512|回复: 32
打印 上一主题 下一主题

绕道解决那些共享打印机必须主机先打,客机才能打的问题

[复制链接]
跳转到指定楼层
1#
发表于 昨天 22:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 窄口牛 于 2026-1-30 00:03 编辑

在主机添加一个计划任务,登录系统后,先打印一张空纸出来。


@echo off
Setlocal enabledelayedexpansion
reg query HKU\S-1-5-20>nul || (
echo;CreateObject^("Shell.Application"^).ShellExecute "%~f0", "", "", "runas", 1 > "%temp%\getadmin.vbs" && cscript //b "%temp%\getadmin.vbs" && exit /b & del "%temp%\getadmin.vbs" /f /q>nul 2>nul)
pushd "%CD%" && CD /D "%~dp0"
set TASK_NAME="PrinterOnlineMonitor"
set SCRIPT_PATH="%SystemRoot%\printer_monitor.vbs"
echo Creating monitor script...
(
rem 下一行修改你的打印机实际名称
echo Dim targetPrinterName
echo targetPrinterName = "HP LaserJet Professional CP1020 Series"
echo Dim maxRetryCount, retryInterval, checkInterval
echo maxRetryCount = 60
echo retryInterval = 5000
echo checkInterval = 30000
echo Set wmi = GetObject^("winmgmts:\\.\root\cimv2"^)
echo Set fso = CreateObject^("Scripting.FileSystemObject"^)
echo Set shell = CreateObject^("WScript.Shell"^)
echo Dim printerFound, printJobStarted, retryCount, lastCheckTime
echo printerFound = False
echo printJobStarted = False
echo retryCount = 0
echo lastCheckTime = Now
echo Do While retryCount ^< maxRetryCount
echo     Set printers = wmi.ExecQuery^("SELECT * FROM Win32_Printer WHERE Name = '" ^& targetPrinterName ^& "'"^)
echo.
echo     For Each printer In printers
echo         printerFound = True
echo         If Not printJobStarted Then
echo             If IsPrinterReady^(printer^) Then
echo                 'WScript.Echo "[" ^& Time ^& "] 打印机就绪,开始打印..."
echo                 Call PrintBlankPage
echo                 printJobStarted = True
echo                 retryCount = 0
echo                 lastCheckTime = Now
echo             Else
echo                 If retryCount Mod 6 = 0 Then
echo                     'WScript.Echo "[" ^& Time ^& "] 打印机不可用: " ^& GetPrinterStatusDetail^(printer^)
echo                 End If
echo             End If
echo         Else
echo             If IsPrinterReady^(printer^) And DateDiff^("s", lastCheckTime, Now^) ^> 10 Then
echo                 If IsPrintJobComplete^(targetPrinterName^) Then
echo                     'WScript.Echo "[" ^& Time ^& "] 打印完成!"
echo                     WScript.Quit 0
echo                 End If
echo                 lastCheckTime = Now
echo             ElseIf DateDiff^("s", lastCheckTime, Now^) ^> 5 Then
echo                 lastCheckTime = Now
echo             End If
echo         End If
echo     Next
echo     If Not printerFound Then
echo         If retryCount Mod 12 = 0 Then
echo             'WScript.Echo "[" ^& Time ^& "] 未找到名为 '" ^& targetPrinterName ^& "' 的打印机。"
echo         End If
echo     End If
echo     retryCount = retryCount + 1
echo     Dim waitTime
echo     If printJobStarted Then
echo         waitTime = 2000
echo     Else
echo         waitTime = retryInterval
echo         If retryCount ^> 12 Then
echo             waitTime = checkInterval
echo         End If
echo     End If
echo     If retryCount ^< maxRetryCount Then
echo         WScript.Sleep waitTime
echo     End If
echo Loop
echo 'WScript.Echo "[" ^& Time ^& "] 错误:打印超时或失败。"
echo WScript.Quit 1
echo Function IsPrinterReady^(printer^)
echo     Dim isReady
echo     Dim isOnline
echo     isOnline = ^(^(printer.Attributes And 128^) = 128^)
echo     Dim isOffline
echo     isOffline = ^(^(printer.Attributes And 256^) = 256^)
echo     Dim hasError
echo     hasError = ^(^(printer.PrinterStatus And 1^) = 1^) Or _  
echo                ^(^(printer.PrinterStatus And 2^) = 2^) Or _  
echo                ^(^(printer.PrinterStatus And 3^) = 3^) Or _  
echo                ^(^(printer.PrinterStatus And 4^) = 4^) Or _  
echo                ^(^(printer.PrinterStatus And 5^) = 5^)      
echo     Dim isInErrorState
echo     isInErrorState = False
echo     Select Case printer.PrinterState
echo         Case 1:
echo             isInErrorState = True
echo         Case 2:
echo             isInErrorState = True
echo         Case 5:
echo             isInErrorState = True
echo         Case 6:
echo             isInErrorState = True
echo         Case 7:
echo             isInErrorState = True
echo         Case 8:
echo             isInErrorState = True
echo         Case 9:
echo             isInErrorState = True
echo         Case 10:
echo             isInErrorState = True
echo         Case 11:
echo             isInErrorState = True
echo         Case 4194432:
echo             isInErrorState = True
echo     End Select
echo     isReady = isOnline And ^(Not isOffline^) And ^(Not isInErrorState^) And _
echo               ^(printer.PrinterState = 0 Or printer.PrinterState = 3 Or printer.PrinterState = 4^)
echo     IsPrinterReady = isReady
echo End Function
echo Function GetPrinterStatusDetail^(printer^)
echo     Dim statusText
echo     statusText = "状态码: " ^& printer.PrinterState ^& "(" ^& GetPrinterStateDescription^(printer.PrinterState^) ^& ")"
echo     Dim isOnline, isOffline
echo     isOnline = ^(^(printer.Attributes And 128^) = 128^)
echo     isOffline = ^(^(printer.Attributes And 256^) = 256^)
echo     If Not isOnline Then
echo         statusText = statusText ^& " [未联机]"
echo     End If
echo     If isOffline Then
echo         statusText = statusText ^& " [脱机]"
echo     End If
echo     Select Case printer.PrinterState
echo         Case 5
echo             statusText = statusText ^& " [纸张问题]"
echo         Case 6
echo             statusText = statusText ^& " [无纸张]"
echo         Case 7, 10
echo             statusText = statusText ^& " [需要用户干预]"
echo         Case 8
echo             statusText = statusText ^& " [卡纸]"
echo         Case 9
echo             statusText = statusText ^& " [缺纸]"
echo         Case 11
echo             statusText = statusText ^& " [未就绪]"
echo         Case 4194432
echo             statusText = statusText ^& " [脱机状态]"
echo     End Select
echo     If printer.Status ^<^> "" Then
echo         statusText = statusText ^& " - " ^& printer.Status
echo     End If
echo     GetPrinterStatusDetail = statusText
echo End Function
echo Function GetPrinterStateDescription^(state^)
echo     Select Case state
echo         Case 0: GetPrinterStateDescription = "就绪"
echo         Case 1: GetPrinterStateDescription = "暂停"
echo         Case 2: GetPrinterStateDescription = "错误"
echo         Case 3: GetPrinterStateDescription = "空闲"
echo         Case 4: GetPrinterStateDescription = "打印中"
echo         Case 5: GetPrinterStateDescription = "纸张问题"
echo         Case 6: GetPrinterStateDescription = "无纸张"
echo         Case 7: GetPrinterStateDescription = "需要用户干预"
echo         Case 8: GetPrinterStateDescription = "卡纸"
echo         Case 9: GetPrinterStateDescription = "缺纸"
echo         Case 10: GetPrinterStateDescription = "需要用户干预"
echo         Case 11: GetPrinterStateDescription = "未就绪"
echo         Case 16: GetPrinterStateDescription = "初始化"
echo         Case 18: GetPrinterStateDescription = "预热"
echo         Case 4194432: GetPrinterStateDescription = "脱机"
echo         Case Else: GetPrinterStateDescription = "未知状态"
echo     End Select
echo End Function
echo Function IsPrintJobComplete^(printerName^)
echo     On Error Resume Next
echo     Dim printJobs, job
echo     Set printJobs = wmi.ExecQuery^("SELECT * FROM Win32_PrintJob"^)
echo     IsPrintJobComplete = True
echo     For Each job In printJobs
echo         If InStr^(1, job.Name, printerName, vbTextCompare^) ^> 0 Then
echo             ' JobStatus: 1 = Paused, 2 = Error, 3 = Deleting, 4 = Printing, 5 = Offline, 6 = Paperout, 7 = Printed
echo             If job.JobStatus ^<^> 7 Then
echo                 Dim jobTime
echo                 jobTime = CDate^(Mid^(job.TimeSubmitted, 1, 4^) ^& "-" ^& _
echo                                Mid^(job.TimeSubmitted, 5, 2^) ^& "-" ^& _
echo                                Mid^(job.TimeSubmitted, 7, 2^) ^& " " ^& _
echo                                Mid^(job.TimeSubmitted, 9, 2^) ^& ":" ^& _
echo                                Mid^(job.TimeSubmitted, 11, 2^) ^& ":" ^& _
echo                                Mid^(job.TimeSubmitted, 13, 2^)^)
echo                 If DateDiff^("n", jobTime, Now^) ^< 5 Then
echo                     IsPrintJobComplete = False
echo                     Exit Function
echo                 End If
echo             End If
echo         End If
echo     Next
echo End Function
echo Sub PrintBlankPage^(^)
echo     Dim tempFile
echo     tempFile = shell.ExpandEnvironmentStrings^("%%TEMP%%"^) ^& "\blank_print_" ^& Year^(Now^) ^& Month^(Now^) ^& Day^(Now^) ^& Hour^(Now^) ^& Minute^(Now^) ^& Second^(Now^) ^& ".txt"
echo     Dim tf
echo     Set tf = fso.CreateTextFile^(tempFile, True^)
echo     tf.Write "        "
echo     tf.Close
echo     On Error Resume Next
echo     shell.Run "NOTEPAD.EXE /P """ ^& tempFile ^& """", 0, False
echo     WScript.Sleep 3000
echo     If fso.FileExists^(tempFile^) Then
echo         On Error Resume Next
echo         fso.DeleteFile^(tempFile^)
echo     End If
echo     Set tf = Nothing
echo End Sub
)> %SCRIPT_PATH%
echo Creating scheduled task...
schtasks /create /tn %TASK_NAME% /tr "%SystemRoot%\System32\wscript.exe %SCRIPT_PATH%" /sc onlogon /ru System /rl HIGHEST /f




打印空白文档.rar

2.39 KB, 下载次数: 24, 下载积分: 无忧币 -2

评分

参与人数 1无忧币 +5 收起 理由
wu733 + 5 很给力!

查看全部评分

来自 19#
 楼主| 发表于 9 小时前 来自手机 | 只看该作者
本帖最后由 窄口牛 于 2026-1-30 09:31 编辑

运行一次,会在任务计划添加一个用户登陆以后的任务,来运行windows目录下的一个vbs去循环检测打印机状态,打印机正常后过一张白纸。
回复

使用道具 举报

2#
发表于 昨天 22:59 | 只看该作者
一般不会出现这种情况吧。办公室的打印机,都是共享的。
回复

使用道具 举报

3#
发表于 昨天 23:54 | 只看该作者
这个问题很经典,没碰到过的就不知道
回复

使用道具 举报

4#
 楼主| 发表于 19 小时前 | 只看该作者
更新修复只检测一次问题
回复

使用道具 举报

5#
发表于 18 小时前 | 只看该作者
哪里来这些毛病哦..
回复

使用道具 举报

6#
发表于 12 小时前 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

7#
发表于 10 小时前 | 只看该作者
共享打印机确实没有碰到这个问题
回复

使用道具 举报

8#
 楼主| 发表于 10 小时前 | 只看该作者
我也首次遇到,但是bug11有啥问题都是非常正常的,没有问题才不正常。
回复

使用道具 举报

9#
发表于 10 小时前 | 只看该作者
这个问题很少见,但确实是会有,我就遇到过HP的共享打印机,必须主机要先打一张,不然客机绝对不能打的情况。

点评

谢谢分享  详情 回复 发表于 5 小时前
回复

使用道具 举报

10#
发表于 10 小时前 | 只看该作者
这个确实没遇到过,楼主这是什么情况啊?
回复

使用道具 举报

11#
发表于 10 小时前 | 只看该作者
感谢分享
回复

使用道具 举报

12#
发表于 10 小时前 | 只看该作者
没遇到过
回复

使用道具 举报

13#
发表于 10 小时前 | 只看该作者
第一次听说还有这种情况。
回复

使用道具 举报

14#
发表于 10 小时前 | 只看该作者
支持原创
回复

使用道具 举报

15#
发表于 10 小时前 | 只看该作者
遇到过。。所以解决方法是宿主机开机自动打印一张?
回复

使用道具 举报

16#
发表于 10 小时前 | 只看该作者
惠普126A打印机共享后,会出现主机端必须打印一张,客户端才可以打印的,请问你这个直接直接运行一次就可以解决了吗?还是每天也运行一次的呢
回复

使用道具 举报

17#
发表于 9 小时前 | 只看该作者
这个问题确实存在。可有大佬有更直接的修复方案

点评

我没有试,你可以试试,因为测试得反复重启主机。可以安装本地打印机,然后把本地端口映射为网络端口。 之前想设置直接打印到打印机,但bug11报错,无效的设置句柄,我觉得直接打印到打印机也有可能有帮助。  详情 回复 发表于 9 小时前
回复

使用道具 举报

18#
发表于 9 小时前 | 只看该作者
感谢分享,学习一下,目前没有遇到过类似现象。
回复

使用道具 举报

20#
 楼主| 发表于 9 小时前 来自手机 | 只看该作者
mapleoath 发表于 2026-1-30 09:05
这个问题确实存在。可有大佬有更直接的修复方案

我没有试,你可以试试,因为测试得反复重启主机。可以安装本地打印机,然后把本地端口映射为网络端口。
之前想设置直接打印到打印机,但bug11报错,无效的设置句柄,我觉得直接打印到打印机也有可能有帮助。
回复

使用道具 举报

21#
发表于 9 小时前 | 只看该作者
没见过,我一般避免使用HP的打印机
回复

使用道具 举报

22#
发表于 8 小时前 | 只看该作者
猜测以下, 是惠普的 gdi+ 类型的打印机
这种打印机本身固件是不完整的,初始化时需要主机复制固件到打印机
用linux的cups 共享可以解决问题
回复

使用道具 举报

23#
发表于 8 小时前 | 只看该作者
感谢分享
回复

使用道具 举报

24#
发表于 6 小时前 | 只看该作者
偶尔遇到,打印机固件还是系统共享的问题?
回复

使用道具 举报

25#
发表于 6 小时前 | 只看该作者
谢谢分享
回复

使用道具 举报

26#
发表于 5 小时前 | 只看该作者
用USB打印服务器,然后你会发现打印从此不再有任何感觉...


二○二六年一月三十日
回复

使用道具 举报

27#
发表于 5 小时前 | 只看该作者
fabin 发表于 2026-1-30 08:15
这个问题很少见,但确实是会有,我就遇到过HP的共享打印机,必须主机要先打一张,不然客机绝对不能打的情况 ...

谢谢分享
回复

使用道具 举报

28#
发表于 5 小时前 来自手机 | 只看该作者
感谢楼主分享
回复

使用道具 举报

29#
发表于 5 小时前 | 只看该作者
多打印机共享的时候小问题比较多
回复

使用道具 举报

30#
发表于 4 小时前 | 只看该作者

没遇到过
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2026-1-30 19:04

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表