powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Изменение настроек принтера по-умолчанию
4 сообщений из 4, страница 1 из 1
Изменение настроек принтера по-умолчанию
    #38375758
hdb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hdb
Гость
Всем доброго времени суток, суть моей проблемы вот в чем:
По работе необходимо написать внешнюю программу/скрипт, который бы изменял настройки принтера (пользователи нынче пошли ленивые, не знают/могут где-что нужно переключать чтобы поменять ориентацию при печати документа). Т.о. изменяться должны настройки принтера по-умолчанию. Пробовал использовать скрипты на VBS, наподобие:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_PrinterConfiguration")

For Each objPrinter in colInstalledPrinters
    Wscript.Echo "Name: " & objPrinter.Name
	objPrinter.Orientation=2
     objPrinter.put_
Next


Но все свелось к:
автор Unfortunately, that technique won't work. The Win32_PrinterConfiguration properties are read-only.
Тогда я попробовал провернуть все через драйвер winspool.drv как указано ниже:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
Option Explicit

 Private Const CCHDEVICENAME = 32
 Private Const CCHFORMNAME = 32

 Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
 Private Const PRINTER_ACCESS_ADMINISTER = &H4
 Private Const PRINTER_ACCESS_USE = &H8
 Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
 PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)

 Private Const DM_MODIFY = 8
 Private Const DM_IN_BUFFER = DM_MODIFY
 Private Const DM_COPY = 2
 Private Const DM_OUT_BUFFER = DM_COPY
 Private Const DMORIENT_PORTRAIT = 1
 Private Const DMORIENT_LANDSCAPE = 2
 Private Const DM_ORIENTATION = &H1

 Private Type DEVMODE
 dmDeviceName As String * CCHDEVICENAME
 dmSpecVersion As Integer
 dmDriverVersion As Integer
 dmSize As Integer
 dmDriverExtra As Integer
 dmFields As Long
 dmOrientation As Integer
 dmPaperSize As Integer
 dmPaperLength As Integer
 dmPaperWidth As Integer
 dmScale As Integer
 dmCopies As Integer
 dmDefaultSource As Integer
 dmPrintQuality As Integer
 dmColor As Integer
 dmDuplex As Integer
 dmYResolution As Integer
 dmTTOption As Integer
 dmCollate As Integer
 dmFormName As String * CCHFORMNAME
 dmLogPixels As Integer
 dmBitsPerPel As Long
 dmPelsWidth As Long
 dmPelsHeight As Long
 dmDisplayFlags As Long
 dmDisplayFrequency As Long
 dmICMMethod As Long
 dmICMIntent As Long
 dmMediaType As Long
 dmDitherType As Long
 dmReserved1 As Long
 dmReserved2 As Long
 End Type

 Private Type PRINTER_DEFAULTS
 pDatatype As String
 pDevMode As Long
 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 SetPrinter Lib "winspool.drv" Alias "SetPrinterA" _
 (ByVal hPrinter As Long, ByVal Level As Long, pPrinter As Any, ByVal Command _
 As Long) As Long
 Private Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" _
 (ByVal hPrinter As Long, ByVal Level As Long, pPrinter As Any, ByVal cbBuf As _
 Long, pcbNeeded As Long) As Long
 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As _
 Any, hpvSource As Any, ByVal cbCopy As Long)
 Private Declare Function ClosePrinter Lib "winspool.drv" (ByValhPrinter As _
 Long) As Long

 Private Declare Function DocumentProperties Lib "winspool.drv" Alias _
 "DocumentPropertiesA" (ByVal hwnd As Long, ByVal hPrinter As Long, ByVal _
 pDeviceName As String, ByVal pDevModeOutput As Any, ByVal pDevModeInput As _
 Any, ByVal fMode As Long) As Long

 Public Sub SetOrientation(NewOrientation As Long, Optional ByVal m_hwnd As Long)
 'On Error GoTo eh
 Dim PrinterHandle As Long
 Dim PrinterName As String
 Dim MyString As String
 Dim pd As PRINTER_DEFAULTS
 Dim lpDevMode As DEVMODE
 Dim Result As Long
 Dim Needed As Long
 Dim pFullDevMode As Long
 Dim pi2_buffer() As Long
  
 PrinterName = Printer.DeviceName
 If PrinterName = "" Then
 Exit Sub
 End If

 pd.pDatatype = vbNullString
 pd.pDevMode = 0&
 pd.DesiredAccess = PRINTER_ALL_ACCESS

 Result = OpenPrinter(PrinterName, PrinterHandle, pd)    
 Result = GetPrinter(PrinterHandle, 2, ByVal 0&, 0, Needed)
 
ReDim pi2_buffer((Needed \ 4))
 Result = GetPrinter(PrinterHandle, 2, pi2_buffer(0), Needed, Needed)
 pFullDevMode = pi2_buffer(7)
 Call CopyMemory(lpDevMode, ByVal pFullDevMode, Len(lpDevMode))

 lpDevMode.dmOrientation = NewOrientation
 lpDevMode.dmFields = DM_ORIENTATION
 Call CopyMemory(ByVal pFullDevMode, lpDevMode, Len(lpDevMode))

 Result = DocumentProperties(m_hwnd, PrinterHandle, PrinterName, ByVal _
 pFullDevMode, ByVal pFullDevMode, DM_IN_BUFFER Or DM_OUT_BUFFER)
 Result = SetPrinter(PrinterHandle, 2, pi2_buffer(0), 0&)
 Call ClosePrinter(PrinterHandle)

 Dim p As Printer
 For Each p In Printers
 If p.DeviceName = PrinterName Then
 Set Printer = p
 Exit For
 End If
 Next p
 Printer.Orientation = lpDevMode.dmOrientation
 Exit Sub
eh:
Label2.Caption = "Error occured during executing"
 End Sub



Процедура отрабатывает корректно и при вызове с нужными параметрами изменяет ориентацию листа принтера по-умолчанию. Но только если запускать "от имени Администратора" или в среде разработки (Microsoft Visual Basic 6-Portable). Если вызывать исполнение этой программы из другой или просто запускать из директории, то ничего не происходит.

В ходе дебаггинга, выяснилось что проблема в получении дексриптора принтера (
Код: vbnet
1.
переменная PrinterHandle

):
Код: vbnet
1.
 Result = OpenPrinter(PrinterName, PrinterHandle, pd)    


При вызове не "от имени администратора", в Result возвращается 0, а в PrinterHandle соответственно не пишется дексриптор. (вот тут про функцию: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx )
Что можно с этим сделать? По какой причине функция так себя ведет? Заранее спасибо!
(П.С. До этого момента c VB почти не работал, поэтому большая просьба писать советы как можно подробней)
...
Рейтинг: 0 / 0
Изменение настроек принтера по-умолчанию
    #38376237
AlexShiryaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуйте посмотреть в сторону команды rundll32 printui.dll,PrintUIEntry
У нас была аналогичная задача, только с включением двухсторонней печати.
В итоге остановились на этой команде.
Предварительно принтер настраивается как нужно и сохраняются настройки в файл
rundll32 printui.dll,PrintUIEntry /Ss /n "HP4515" /a "c:\temp\config.bin" d u g 8
затем перед печатью настройки восстанавливаются.
rundll32 printui.dll,PrintUIEntry /Sr /n "HP4515" /a "c:\temp\config.bin" d u g 8
Из VB эту команду можно вызывать при помощи Shell (если мне не изменяет память).

Но это работает если знаете имя принтера в системе.
...
Рейтинг: 0 / 0
Изменение настроек принтера по-умолчанию
    #38380952
hdb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hdb
Гость
AlexShiryaevПопробуйте посмотреть в сторону команды rundll32 printui.dll,PrintUIEntry
У нас была аналогичная задача, только с включением двухсторонней печати.
В итоге остановились на этой команде.
Предварительно принтер настраивается как нужно и сохраняются настройки в файл
rundll32 printui.dll,PrintUIEntry /Ss /n "HP4515" /a "c:\temp\config.bin" d u g 8
затем перед печатью настройки восстанавливаются.
rundll32 printui.dll,PrintUIEntry /Sr /n "HP4515" /a "c:\temp\config.bin" d u g 8
Из VB эту команду можно вызывать при помощи Shell (если мне не изменяет память).

Но это работает если знаете имя принтера в системе.
Благодарю за совет, свою проблему я решил аналогичным способом. Подробности ниже:
Вызов API из 1С:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Процедура КомандаАПИ(парам1)	
    Shell = Новый COMОбъект("WScript.Shell");
    Shell.Run(парам1);
    //Исскуственно вводимая задержка, для того чтобы предыдущая команда успела завершить свое выполнение
    //и вывела выходные данные в файл, если это требуется (на сохранение файла необходимо порядка 30 мс)
    Shell=Новый COMОбъект("WScript.Shell");
    Shell.Run("ping -n 1 -w 100 1.1.1.1",0,-1);
КонецПроцедуры


Получение списка доступных принтеров на данном ПК:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
Процедура  Сформировать()
	// Все принтера (доступные)
	wshNetwork    = Новый COMОбъект ("WScript.Network");
	oPrinters        = wshNetwork.EnumPrinterConnections();
	Если oPrinters.Count()>0 Тогда
		//    Принтер по умолчанию
		wshPrint = Новый COMОбъект("WScript.Shell");
		Prn = wshPrint.RegRead("HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device");
		
		// Удаление лишней информации
		Позиция = Найти(Prn, ",");
		Если Позиция > 0 Тогда
			Prn=Лев(Prn,Позиция-1)
		КонецЕсли;
		Принтеры.Очистить();
		
		//Заполнение таблицы именами доступных принтеров
		i  = 0;
		Пока i < oPrinters.Count() - 1 Цикл
			СтрТЧ=Принтеры.Добавить();
			СтрТЧ.ИмяПринтера=oPrinters.Item(i+1);
			Если oPrinters.Item(i+1)=Prn Тогда 
				СтрТч.ПоУмолчанию=Истина;
			Иначе
				СтрТч.ПоУмолчанию=Ложь;
			КонецЕсли;	
			i = i + 2;
		КонецЦикла;
	Иначе
		Сообщить("Настройка невозможна поскольку список доступных принтеров пуст");
		Возврат ;
	КонецЕсли;
КонецПроцедуры


Получение настроек печати выбранного принтера:
Код: plaintext
1.
2.
3.
4.
Процедура ShellProperties()
	LabelPrinter=""""+ВыбранныйПринтер+"""";
	КомандаАПИ("RUNDLL32 PRINTUI.DLL,PrintUIEntry /e /n " + LabelPrinter +" ");		
КонецПроцедуры


Сохраняем настройки выбранного принтера в файл
Код: plaintext
1.
2.
3.
4.
5.
6.
Функция ShellStore()	
	LabelPrinter=""""+ВыбранныйПринтер+"""";
	PathToSettings=""""+КаталогВременныхФайлов()+"Printer_Description_1C.dat"+"""";
	КомандаАПИ("RUNDLL32 PRINTUI.DLL,PrintUIEntry /Ss /n " + LabelPrinter + " /a "+PathToSettings+" d u");
	......
КонецФункции


Загрузка настроек выбранного принтера из файла:
Код: plaintext
1.
2.
3.
4.
5.
6.
Процедура Загрузить(Команда)	
           .......
	LabelPrinter=""""+пИмяПринтера+"""";
	PathToSettings=""""+ИмяФайла+"""";
	КомандаАПИ("RUNDLL32 PRINTUI.DLL,PrintUIEntry /Sr /n " + LabelPrinter + " /a "+PathToSettings+" d u ");
КонецПроцедуры


Не совсем понятно почему у вас были одновременно флаги "u" и "g", я оставил только "d u" - и все работает:
Код: plaintext
1.
2.
3.
Флаги при записи или чтении параметров принтера, помещаемые в конце команды:
	d	PrinterData
	g	глобальный DevMode
	u	пользовательский DevMode
Как уже понятно из листингов выше, основное приложение написано на 1С, и с помощью команд API осуществляется преобразование настроек принтера в файл настроек, затем файл в двоичном виде пишется в БД 1С и в итоге настройки хранятся там. При необходимости замены настроек печати, осуществляется последовательное обратное преобразование.
Возможно кому-то данная тема поможет решить аналогичную проблему в своей среде разработки.
Вот еще ссылка в помощь: http://настройкапк.рф/Rundll32.exe
...
Рейтинг: 0 / 0
Изменение настроек принтера по-умолчанию
    #38449709
Movel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hdb, сейчас тоже в 1С пытаюсь решить подобную проблему, и такой вопрос - сначала делаете установки принтера вручную, сохраняете их в файл, и когда нужно эти настройки загружаются из файла?
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Изменение настроек принтера по-умолчанию
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]