Термопринтеры Zebra и печать через удаленный рабочий стол (RDP)

  • 04.07.2023
  • 1 530
  • 0
  • 1
  • 1
  • 0
Термопринтеры Zebra и печать через удаленный рабочий стол (RDP)

При использовании термопринтеров производителя Zebra (в описываемом случае это были модели LP 2824 Plus и ZD410), обнаружилась одна неприятная проблема - плохое качество печати штрихкодов с принтера, проброшенного на терминальный сервер через удаленный рабочий стол. Качество штрихкодов получалось настолько неудовлетворительным, что сканеры штрихкодов не могли корректно считать содержимое штрихкода.

Ниже будет описан мой способ решения данной проблемы.

Отключение использование Easy Print

Проблема плохого качества печати кроется в некорректной работе драйвера устройства с технологией Easy Print. Соответственно, единственным вариантом решения проблемы становится отключение Easy Print на терминальном сервере, и установка на нем драйвера для нужного принтера Zebra. Подробнее, про отключение Easy Print можно прочитать в отдельной статье. Для установки драйвера принтера Zebra, можно воспользоваться либо диспетчером сервера печати, либо создав виртуальный принтер на каком-нибудь свободном порте (к примеру, LPT).

Настройка принтера

После отключения использования Easy Print, и установки нужного драйвера, проброшенный принтер должен начать использовать свой родной драйвер. Вот тут появится другой неприятный момент - каждый раз, проброшенный принтер будет сбрасывать свои настройки, в том числе настройки размера бумаги. В итоге, после этого, печатается четкое изображение, но с некорректным размером. Причина столь неприятного поведения кроется в том, что настройки принтера сохраняются в реестре, используя название принтера - которое в свою очередь, при подключении через удаленный рабочий стол, постоянно меняется, за счет добавления номера сессии в его имя.

Для исправления данной ситуации, можно экспортировать настройки принтера, и принудительно их импортировать при подключении клиента, через vbs скрипт. Для этого, нужно выполнить следующие действия:

В качестве примера, ниже приведена настройка под принтер Zebra LP 2824 Plus.
  1. Подключаемся на терминальный сервер с компьютера, где подключен нужный принтер Zebra. Убеждаемся, что принтер успешно проброшен на сервер.
  2. Открываем настройки принтера, и выставляем нужные. Сохраняем.
  3. Открываем Редактор реестра, и переходим в раздел HKEY_CURRENT_USER\Printers\DevModePerUser. Находим в данном разделе двоичный параметр с наименованием проброшенного принтера.
  4. Экспортируем ветку реестра, в любое удобное место.
  5. Открываем получившийся файл реестра, удаляем все лишние принтеры, и оставляем только нужный. Затем, меняем наименование принтера на <PRINTERNAME>. В итоге должно получится так, как на скриншоте ниже.

    Сохраняем его в директорию где к нему будут иметь доступ все пользователи - например, C:\Scripts\Printers. Файлу следует указать имя, соответствующее модели принтера - в данном случае, это будет LP2824Plus.
  6. Теперь, в директории C:\Scripts создаем VBS скрипт следующего содержания:
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objRegEx = CreateObject("VBScript.RegExp")
    Set objShell = CreateObject("WScript.Shell")
    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    
    ' Процедура импорта настроек принтера
    Sub ImportPrinterSettings(PrinterModel)
    	' Открываем файл реестра с настройками принтера и считываем его
    	Set objSettingsFile = objFSO.OpenTextFile("C:\Scripts\Printers\" & PrinterModel & ".reg", 1, True, -1)
    	strSettingsFileContent = objSettingsFile.ReadAll
    	objSettingsFile.Close
    	' Заменяем имя принтера в данном файле
    	strSettingsFileContentReplace = Replace(strSettingsFileContent, "<PRINTERNAME>", objPrinter.Name)
    	' Сохраняем настройки во временный файл
    	strTempSettingsFileName = objFSO.GetTempName
    	Set objTempSettingsFile = objFSO.OpenTextFile(objShell.ExpandEnvironmentStrings("%temp%") & "\" & strTempSettingsFileName, 2, True, -1)
    	objTempSettingsFile.Write strSettingsFileContentReplace
    	objTempSettingsFile.Close
    	' Импортируем файл настроек в реестр
    	objShell.Run("reg import " & objShell.ExpandEnvironmentStrings("%temp%") & "\" & strTempSettingsFileName), 0, True
    End Sub
    
    ' Ждем 10 секунд
    WScript.Sleep 10000
    
    ' Получаем список принтеров
    Set colPrinters = objWMIService.ExecQuery ("SELECT DriverName, Name FROM Win32_Printer")
    
    ' Ищем в списке принтеров нужный принтер
    For Each objPrinter in colPrinters
    	' Устанавливаем регулярное выражение, для проверки, что принтер был перенаправлен
    	objRegEx.Pattern = "^(.*?)(перенаправлено \d)"
    	' Zebra LP 2824 Plus
    	If objRegEx.Test(objPrinter.Name) AND InStr(objPrinter.DriverName,"ZDesigner LP 2824 Plus (ZPL)") > 0 Then
    		ImportPrinterSettings("LP2824Plus")
    	End If
    Next
  7. Создадим ярлык для созданного VBS файла, и поместим его в директорию C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp. Теперь, при заходе на сервер, у всех пользователей будет срабатывать данный скрипт.

Вариант для RemoteApp

Описанный выше вариант прекрасно подходит для обычного терминального сервера, но совершенно не годиться для использования с приложениями RemoteApp, поскольку в таком случае, при запуске сессии пользователя, автозагрузка полностью игнорируется. Единственным решением в данном случае будет создать отдельный VBS скрипт под нужное приложение, добавив туда в конце запуск нужного исполняемого файла, а в настройках RemoteApp изменить путь к приложению на путь к данному скрипту.

Так же, стоит учесть, что в скрипте присутствует 10 секундная задержка - и если в случае с терминальным сервером, она особо не заметна, то при запуске RemoteApp приложения, пользователь будет просто ждать все 10 секунд.

Для того, чтобы сделать ожидание пользователя более информативным, создадим HTA приложение, которое будет закрываться через 10 секунд. Создадим HTA файл следующего содержания (кодировка CP1251 обязательна, иначе будет не читабельный текст!):

<head>
	<hta:application border="none" caption="no" contextMenu="no" innerborder="no" maximizeButton="no" scroll="no"/>
	<script language="VBScript">
		window.resizeTo 470,80
	</script>
	<style>
		body {
			background-color: #f0f0f0;
			font-family: Arial;
			text-align: center;
		}
		.main {
			padding-bottom: 40px;
		}
		.main div {
			float: left;
		}
		.main img {
			max-height: 48px;
			max-width: 48px;
		}
		.main .text {
			font-size: 13px;
			width: 100%;
		}
		.main .title {
			font-size: 14px;
			font-weight: bold;
			width: 100%;
		}
	</style>
	<title>Запуск программы</title>
</head>
<body onmousewheel="javascript:if(window.event.ctrlKey){return false}">
	<div class="main">
		<div>
			<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAJ1BMVEUAAAB/f3/AwMD///8AAAAAAIAAAP8A//8AgIAA/wAAgACAgAD//wA6t+/tAAAAAXRSTlMAQObYZgAAAAFiS0dEAxEMTPIAAAAHdElNRQfiBhoALCAl4xkUAAABHklEQVQ4y82TMW7DMAxFJSAHCB1vXSo3W5ZYHushTo0iQKcgyBVyhKBH6Nyta8deIUfwpUpFJikxDZAhQ/+oB5HU/5QxxlhgmUxFRapX6bnl8yfIwKwh1Rmwnm84BajzTIN+1E6D10PUJTjeDxz+AdjmuVi/H6VysZ5MV7mw7ToXTlznMhlN71QusiKcSwRcufabj6gRcGG/ef8DOCylwdcngjk21+Dnm0pd7XEbEEcVoIeH5hkIWz2P9l8FFztMgG3XQGwvYZoAmQ+6ohTA46HACUgvQAECJPFz6KWZwsPp1OGMVSKHYNk8t8NL00guWCmAx2rRDmtcHsoFtQ5g1b+1Q9gAyqVysdR5ztR+/eFzUMrSQ6bkO6QP73tjfgEEz7NK1Rcm+AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNi0yNlQwMDo0NDozMi0wNDowMCBSOocAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDYtMjZUMDA6NDQ6MzItMDQ6MDBRD4I7AAAAAElFTkSuQmCC">
		</div>
		<div>
			<p class="title">Идет подготовка к запуску программы</p>
			<p class="text">Пожалуйста, подождите 10 секунд</p>
		</div>
	</div>
	<script language="VBScript">
		Set objShell = CreateObject("WScript.Shell")
		objShell.Run "cmd /c timeout /t 10", 0, 1
		window.close()
	</script>
</body>

Выглядеть выше приведенное HTA-приложение будет следующим образом:

Сохраним данный файл в директорию C:\Scripts, с именем Loader.hta. Теперь, изменим наш VBS скрипт, изменив команду sleep на запуск HTA приложения, а так же добавив в конец запуск нужного приложения (в качестве примера, это будет 1С Предприятие).

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objRegEx = CreateObject("VBScript.RegExp")
Set objShell = CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

' Процедура импорта настроек принтера
Sub ImportPrinterSettings(PrinterModel)
	' Открываем файл реестра с настройками принтера и считываем его
	Set objSettingsFile = objFSO.OpenTextFile("C:\Scripts\Printers\" & PrinterModel & ".reg", 1, True, -1)
	strSettingsFileContent = objSettingsFile.ReadAll
	objSettingsFile.Close
	' Заменяем имя принтера в данном файле
	strSettingsFileContentReplace = Replace(strSettingsFileContent, "<PRINTERNAME>", objPrinter.Name)
	' Сохраняем настройки во временный файл
	strTempSettingsFileName = objFSO.GetTempName
	Set objTempSettingsFile = objFSO.OpenTextFile(objShell.ExpandEnvironmentStrings("%temp%") & "\" & strTempSettingsFileName, 2, True, -1)
	objTempSettingsFile.Write strSettingsFileContentReplace
	objTempSettingsFile.Close
	' Импортируем файл настроек в реестр
	objShell.Run("reg import " & objShell.ExpandEnvironmentStrings("%temp%") & "\" & strTempSettingsFileName), 0, True
End Sub

' Запускаем заглушку на 10 секунд
objShell.Run ("C:\Windows\System32\mshta.exe C:\Scripts\Loader.hta"), 1, True

' Получаем список принтеров
Set colPrinters = objWMIService.ExecQuery ("SELECT DriverName, Name FROM Win32_Printer")

' Ищем в списке принтеров нужный принтер
For Each objPrinter in colPrinters
	' Устанавливаем регулярное выражение, для проверки, что принтер был перенаправлен
	objRegEx.Pattern = "^(.*?)(перенаправлено \d)"
	' Zebra LP 2824 Plus
	If objRegEx.Test(objPrinter.Name) AND InStr(objPrinter.DriverName,"ZDesigner LP 2824 Plus (ZPL)") > 0 Then
		ImportPrinterSettings("LP2824Plus")
	End If
Next

' Запускаем приложение
objShell.Run ("""C:\Program Files (x86)\1cv8\common\1cestart.exe"""), 1, False

Теперь, остается только отредактировать путь в настройках Диспетчера удаленных приложений RemoteApp, после чего все будет готово к использованию.

Была ли эта статья Вам полезна?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Напоминаем Вам, что Ваше сообщение будет опубликовано только после проверки администратором сайта. Обычно это занимает 1-2 рабочих дня.