HP LaserJet 1522, 1536, 3052/3055, 300/400 Color...
Я думаю, многим системным администраторам известны описанные в заголовке мфу, отличаются они, в первую очередь, не очень удобной установкой и от этого имеют дурную славу. Однажды, копируя на очередной компьютер сквозь узкий канал пакет fullsolution для мфу весом около 300 мегабайт, идея разобрать этот инсталлятор и автоматизировать установку вылезла попапом на глаза — работу пришлось приостановить.
Разбором драйвера я занимался уже около полутора лет назад, в то время интернет на эту тему был совершенно пуст. Сейчас быстро погуглил по теперь уже известным мне ключевым словам утилит и нашел немного разрозненной информации. Несмотря на это, я решил. что собранная в одно место информация все равно не помешает, при том, что в этом посте она более полная.
Настроим печать
Первым на запрос по snmp показался мфу HP LaserJet 1536, с него и решил начать. Для начала нужно понять. как его подключать как принтер под Windows 7; пожилую XP отбросил сразу, свежую Windows 8 в домене, есть мнение, мне не увидеть никогда. Вот и повод познакомиться с новым для себя PowerShell, подумал я, который в итоге был чуть ли не основной мотивацией в разборе драйвера. Подключение ip-принтера в Windows 7 состоит из трех этапов (в Windows 8 всё сильно упрощается встроенными командлетами, но про нее я уже говорил — не судьба), сначала создаем ip-порт, потом добавляем драйвер и подключаем, собственно, принтер. Для всех этих этапов в Windows есть уже готовые VBS скрипты, многим, я думаю, знакомые, в Windows 7 путь к ним: С:\Windows\System32\Printing_Admin_Scripts\
Начну с создания порта, этот этап самый простой, имя присвоим такое же как ip:
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs -a -r "192.168.0.30" -h "192.168.0.30" -o RAW -n 9100
Добавление драйвера:
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs -a -m "HP LaserJet M1530 MFP Series PCL 6" -e "Windows NT x86" -h "C:\drivers\1536\"-i "C:\drivers\1536\hpc1530c.inf"
Тут стоит отметить одну важную особенность: имя принтера должно указываться точно так же как оно прописано в inf файле драйвера, ради примера уберите часть имени, скрипт выдаст ошибку: «Не удалось добавить драйвер принтера HP LaserJet Код ошибки Win32 87».
Отрывок файла драйвера с полным именем принтера:
Теперь осталось подключить принтер, для этого я остановился на замечательной программе printui, советую посмотреть на нее поближе, у нее есть интересные ключи.
&rundll32 printui.dll,PrintUIEntry /if /b "HP LaserJet M1530 MFP Series PCL 6" /r "192.168.0.30" /m "HP LaserJet M1530 MFP Series PCL 6" /u /K /q /Gw
Пришло время оформить все это в примерно следующего вида скрипт на PowerShell:
function Add-PrinterPort ($printersource) {
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs `
-a -r $printersource -h $printersource -o RAW -n 9100 | Out-Null
}
function Add-PrinterDriver ($printername, $driverpath) {
$folder = Split-Path $driverPath
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs `
-a -m $printername -e Get-Platform -h $folder -i $driverpath
}
function Get-Platform {
if ([System.Environment]::Is64BitOperatingSystem) {
"Windows x64"
} else {
"Windows NT x86"
}
}
Add-Type -As Microsoft.VisualBasic
$printerSource = [Microsoft.VisualBasic.Interaction]::InputBox("Укажите IP адрес принтера.")
if ($printerSource -match "^192\.168\.0\.[0-9]{1,3}$") {
$printername = "HP LaserJet M1530 MFP Series PCL 6"
$driverpath = "C:\drivers\1536\hpc1530c.inf"
Add-PrinterPort $printersource
Add-PrinterDriver $printername $driverpath
# знак & перед командой переключит режим и паремтры не сломаются
&rundll32 printui.dll,PrintUIEntry /if /b $printername /r $printersource /m $printername /u /K /q /Gw
Start-Sleep -Seconds 10
}
Сканирование
Копаясь в inf файлах драйвера, для поиска правильного имени принтера и попутно вообще разбираясь в структуре драйвера HP, глаз зацепился за следующие строки (выделил жирным):
;Windows Vista
[HP.NT.6.0]
«HP LJ M1530 MFP Series Scan»= WIA_1530_Inst.NT.6.0, USB\vid_03f0&pid_012a&mi_00
«HP LJ M1530 MFP Series Scan»= WIA_1530_NW.NT.6.0,vid_03f0&pid_012a&IP_SCAN
;Windows Vista 64
[HP.NTAMD64.6.0]
«HP LJ M1530 MFP Series Scan»= WIA_1530_Inst_Vista64, USB\vid_03f0&pid_012a&mi_00
«HP LJ M1530 MFP Series Scan»= WIA_1530_NW_Vista64,vid_03f0&pid_012a&IP_SCAN
Тут бы хотелось лирики (казалось бы, при чем тут 1С? если вы понимаете о чём я), но опущусь до сухой констатации: попробуем devcon.exe.
DevCon — это программа с интерфейсом командной строки, которая используется в качестве альтернативы диспетчеру устройств С ее помощью можно включать, выключать, перезапускать, обновлять, удалять и опрашивать отдельные устройства или группы устройств. Программа DevCon также предоставляет необходимые разработчику драйвера сведения, которые недоступны с помощью диспетчера устройств.
support.microsoft.com/kb/311272/ru
Добавляем устройство по ID указав драйвер:
.\devcon.exe /r install C:\drivers\1536scan\hppasc16.inf "vid_03f0&pid_012a&IP_SCAN"
Добавляем в реестр необходимые параметры, запускаем сканирование и… Бинго!
Сканер отлично работает, осталось все это оформить.
Настройки сканера в реестре хранятся по следующим путям:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\IMAGE
Опытным путём определяем необходимые нам ключи реестра:
Для того что бы удобно добавить настройки реестра, создадим процитированный ниже файл, который послужит нам шаблоном для модификации внутри скрипта.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\_ITEM_\DeviceData]
«NetworkDeviceID»="\\hostname:_NETWORK_NAME_.domain.local\\ipaddr:_IP_ADDRESS_\\guid:\\macaddr:_MAC_ADDRESS_\\port:1"
«PortID»="_IP_ADDRESS_"
«NetworkHostName»="_NETWORK_NAME_.domain.local"
«TulipIOType»=dword:00000005
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\IMAGE\_ITEM_\Device Parameters]
«NetworkDeviceID»="\\hostname:_NETWORK_NAME_.domain.local\\ipaddr:_IP_ADDRESS_\\guid:\\macaddr:_MAC_ADDRESS_\\port:1"
«PortID»="_IP_ADDRESS_"
«NetworkHostName»="_NETWORK_NAME_.domain.local"
«MAC»="_MAC_ADDRESS_"
«PortNumber»=«1»
«Index»="_ITEM_"
Готовый скрипт установки сканера примет следующий вид:
$IP_ADDRESS = "192.168.0.30"
$MAC_ADDRESS = "001b00b2cc00"
$NETWORK_NAME = "NPI3CPOF7"
$source = "C:\drivers\1536scan"
$dest = Join-Path (Get-Location).path "\temporary"
Copy-Item $source $dest -Recurse -Force
$dest = Join-Path $dest "\hppasc16.inf"
# devcon лежит в одной директории со скриптом
& .\devcon.exe /r install $dest "vid_03f0&pid_012a&IP_SCAN"
$item = Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Control\Class\"{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}" |
Select-Object -Last 1
$item = $item.Substring($item.Length-4, 4)
$pattern = ".\temporary\1536.reg"
$result = ".\temporary\res.reg"
Get-Content $pattern | ForEach-Object {
$_ -replace "_IP_ADDRESS_", $IP_ADDRESS `
-replace "_MAC_ADDRESS_", $MAC_ADDRESS `
-replace "_NETWORK_NAME_", $NETWORK_NAME `
-replace "_ITEM_", $item
} | Set-Content $result
& regedit /s .\temporary\res.reg
Потираем руки, проверяем — работает, модифицируем под 1522 — работает, победно правим под 3055 — облом…
Сканер не дает выбрать планшет, в меню сканирования доступен только податчик, да и тот отказывается сканировать.
Серьезный разговор с 3055 или, Чувак ты поднял на гору не тот камень
Вот он, LaserJet 3055/3052 — самый вредный парень, на удивление вижу я его чаще всех. На самом деле — скажу по секрету — я начал заниматься им первым — пошел через дебри фильтрации вывода procmon при установке драйвера для поиска чего-нибудь интересного и утонул где-то посередине. Когда очередной раз procmon упал из-за нехватки памяти, я решил отложить эту затею до более дружелюбного и спокойного состояния.
Второй набег на разбор установщика МФУ дал результат: спустя часа полтора разбора логов в недрах вывода установщика была найдена жемчужина — hppniscan01.exe
Запуск с необходимыми параметрами моментально установил сканер в устройства и прописал необходимые ветки реестра:
hppniscan01.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a "192.168.0.30" -n 1
В дистрибутивах драйверов других принтеров HP есть ее шестидесяти четырех разрядная версия, драйвер 3055 же поддерживает только x86 операционные системы.
Драйвера сканера я решил выдернуть из общей папки драйверов и сложить отдельно, необходимые файлы легко читаются из inf-файла драйвера. Дерево получилось следующего вида:
C:\Drivers\Scanners\ip\3055scan\hpgtpusd.dll
C:\Drivers\Scanners\ip\3055scan\hppasc01.cat
C:\Drivers\Scanners\ip\3055scan\hppasc01.dll
C:\Drivers\Scanners\ip\3055scan\hppasc01.inf
C:\Drivers\Scanners\ip\3055scan\hppniscan01.exe
C:\Drivers\Scanners\ip\3055scan\hpptpml3.dll
C:\Drivers\Scanners\ip\3055scan\hpxp3390.dll
C:\Drivers\Scanners\ip\3055scan\Drivers\dot4
C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzidr12.dll
C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipm12.dll
C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipr12.dll
C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipr12.sys
Функция установки сканера теперь стала совсем простой, хоть и с зависимостью от внешней компоненты.
Итоговый вид скрипта, с некоторыми захардкоженными упрощениями, примет следующий вид:
function Add-PrinterPort ($printerSource) {
&cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs `
-a -r $printerSource -h $printerSource -o RAW -n 9100 | Out-Null
}
function Add-PrinterDriver ($printerName, $driverPath) {
$folder = Split-Path $driverPath
&cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs `
-a -m $printerName -e Get-Platform -h $folder -i $driverPath
}
function Get-Platform {
if ([System.Environment]::Is64BitOperatingSystem) {
"Windows x64"
} else {
"Windows NT x86"
}
}
function Add-Scanner ($ipaddress, $printername) {
switch -regex ($printername) {
# добавить других мфу по вкусу
"1530" {
Push-Location 'C:\Drivers\Scanners\ip\1536scan\'
if ($(Get-Platform) -eq "Windows x64") {
.\hppniscan64.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a $ipaddress -n 1
} else {
.\hppniscan01.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a $ipaddress -n 1
}
Pop-Location
}
"(305\d)|(3390)" {
Push-Location 'C:\Drivers\Scanners\ip\3055scan\'
switch -regex ($printername) {
"3050" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3217&IP_SCAN" -a $ipaddress -n 1
}
"3052" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3317&IP_SCAN" -a $ipaddress -n 1
}
"3055" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3417&IP_SCAN" -a $ipaddress -n 1
}
"3390" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3517&IP_SCAN" -a $ipaddress -n 1
}
}
Pop-Location
}
}
}
Add-Type -As Microsoft.VisualBasic
$printerSource = [Microsoft.VisualBasic.Interaction]::InputBox("Укажите IP адрес принтера.")
if ($printersource -match "^192\.168\.0\.[0-9]{1,3}$") {
$printername = "HP LaserJet M1530 MFP Series PCL 6"
$driverpath = "C:\drivers\1536\hpc1530c.inf"
Add-PrinterPort $printersource
Add-PrinterDriver $printername $driverPath
# знак & перед коммандой переключит режим и параметры не сломаются
&rundll32 printui.dll,PrintUIEntry /if /b $printername /r $printersource /m $printername /u /K /q /Gw
Start-Sleep -Seconds 10
Add-Scanner $printersource $printername
}
Этот же способ отлично подходит для всех оказавшихся вокруг меня МФУ от HP, для которых я создал отдельные папки с драйверами и варианты выбора в свитче функции установки сканера.
Список файлов драйвера можно посмотреть в разделах inf-файла с именами [SourceDisksFiles], [RegisterDlls], [WIA_CopyFiles] и далее по файлу. Скриншот по драйверам 3055 и 1536, для наглядности:
Из описанных в этой заметке отрывков кода можно собрать полноценный скрипт автоматической установки МФУ, а если добавить в него немного гуя и snmp, то можно вообще навсегда закрыть для себя тему установки МФУ на новые машины.
На этом на сегодня всё, спасибо за внимание. Если в комментариях подскажут чего не хватает МФУ 3055 для работы при установке первым способом посредством devcon, буду сильно благодарен. Может быть кто-то проделал ту же работу, что и я, но добился больших успехов.
В следующей части,