powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Получение информации _PRINTER_INFO_5 о принтере
19 сообщений из 19, страница 1 из 1
Получение информации _PRINTER_INFO_5 о принтере
    #39509187
Dagmanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
Понадобилось разделить принтеры в системе по принципу локальный/сетевой. пробую делать так:

Код: pascal
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.
var
  i: Integer;
  p: P_PRINTER_INFO_5;
  ABytesNeeded: DWord;
  PH:THandle;
begin
  ListBox1.Items.Clear;
  ListBox2.Items.Clear;
  for i := 0 to Printer.Printers.Count - 1 do
  begin

    ph:=0;
    OpenPrinter(PWideChar(Printer.Printers[I]),PH,nil);
    if PH<>0 then
    begin
      GetPrinter(PH, 5, nil, 0, @ABytesNeeded);
      GetMem(p,ABytesNeeded);
      GetPrinter(PH, 5, p, ABytesNeeded, @ABytesNeeded);
      if getlasterror <> 0 then
        raiselastoserror;

      if ((p^.Attributes and PRINTER_ATTRIBUTE_LOCAL) <> 0) then
      begin
          //если он локальный
        ListBox1.Items.add(p^.pPrinterName+' | '+ p^.pPortName);
      end
      else
        ListBox2.Items.add(p^.pPrinterName+' | '+ p^.pPortName);

      FreeMem(p);
    end;
    ClosePrinter(ph);
  end;
end;


( P_PRINTER_INFO_5 = ^_PRINTER_INFO_5; )


Но постоянно получаю ошибку:
"System Error. Code: 122.
Область данных, переданная по системному вызову, слишком мала."

Подскажите, пожалуйста, что делаю не так?
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509200
Mr.Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуйте вместо GetMem\FreeMem использовать GlobalAllocPtr\GlobalFreePtr
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509207
Dagmanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
решил проблему выделением заведомо достаточного количества памяти:

Код: pascal
1.
2.
      GetMem(p,10240);
      GetPrinter(PH, 5, p, 10240, @ABytesNeeded);



Спасибо большое за ответы.
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509213
Mr.Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
там проблема скорее всего в memory alignment
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509234
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dagmanor,

А зачем так сложно?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var 
  ...
  p: _PRINTER_INFO_5;
  ABytesNeeded: DWord;
  ...
begin
  ...
      GetPrinter(PH, 5, @p, SizeOf(p), @ABytesNeeded);
      if getlasterror <> 0 then
  ...
end;


Не вариант?
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509237
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,
Хотя, блин, там строки же...
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509238
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dagmanor
Код: pascal
1.
      GetPrinter(PH, 5, nil, 0, @ABytesNeeded);



приведи декларацию функции GetPrinter
Их может быть несколько, тогда надо будет проверить, какая конкретно используется

меня смущает последний параметр весьма


Dagmanor
Код: pascal
1.
PWideChar(Printer.Printers[I]



Здесь надёжнее PChar


Dagmanor
Код: pascal
1.
2.
      if getlasterror <> 0 then
        raiselastoserror;



Правильнее
Код: sql
1.
 CheckWin32Error( GetPrinter(PH, 5, p, ABytesNeeded, @ABytesNeeded) );
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509240
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

там все проще, издержки копипаста

он ДВА РАЗА вызывает функцию GetPrinter и НИ ОДНОГО РАЗА не проверяет е результат

ПЕРВАЯ вызов функции выставляет ошибку ( SetLastError ), но он её сразу не проверяет

а вот после ВТОРОГО вызова он ее проверяет и выбрасывает исключение

но это была ошибка ПЕРВОГО вызова, а не ВТОРОГО
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509244
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DagmanorПонадобилось разделить принтеры в системе по принципу локальный/сетевой

в принципе ещё можно WMI использовать, но будет медленно и через брандммауэр

хато единообразно для любого жеоеза и декларативно, псевдо-SQL
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509250
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var 
  ...
  p: _PRINTER_INFO_5;
  ABytesNeeded: DWord;
  ...
begin
  ...
      GetPrinter(PH, 5, @p, SizeOf(p), @ABytesNeeded);
      if getlasterror <> 0 then
  ...
end;


Не вариант?

опасно

в другой версии Windows структуру _PRINTER_INFO_5 вдруг как расширят, размер увеличат - и скомпилированная 5 лет назад программа начнёт выдавать ошибку
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509278
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochопасно

в другой версии Windows структуру _PRINTER_INFO_5 вдруг как расширят, размер увеличат - и скомпилированная 5 лет назад программа начнёт выдавать ошибку
Нет, проблема в том что структура содержит строки, а такие структуры, AFAIR, винда возвращает прикрепляя данные в её "хвост". Т.е. SizeOf(p) вернёт нам размер структуры без учета памяти под строки . Поэтому необходимо сначала получать размер и после выделять память, т.к. в этот размер входит не только размер структуры но и размер всех строк.
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509286
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochв другой версии Windows структуру _PRINTER_INFO_5 вдруг как расширят, размер увеличат - и скомпилированная 5 лет назад программа начнёт выдавать ошибку

Это фантастика.
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509315
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi,

в Windows очень много структур, в которых первое поле - это "размер структуры"

это типовой сценарий

именно потому что за десятилетия жизни Windows эти структуры развивались и их размер увеличивался, и поле "размер вот этой самой структуры" тем самым обеспечивает и версионность самой структуры и совместиость старых програм с новыми структурами в новых Windows
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509353
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochэто типовой сценарий

В данном конкретном случае проще сделать _PRINTER_INFO_11, чем ломать совместимость.
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509376
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochschi,

в Windows очень много структур, в которых первое поле - это "размер структуры"

это типовой сценарий

именно потому что за десятилетия жизни Windows эти структуры развивались и их размер увеличивался, и поле "размер вот этой самой структуры" тем самым обеспечивает и версионность самой структуры и совместиость старых програм с новыми структурами в новых Windows

Код: pascal
1.
2.
3.
4.
5.
6.
7.
  _PRINTER_INFO_5W = record
    pPrinterName: PWideChar;
    pPortName: PWideChar;
    Attributes: DWORD;
    DeviceNotSelectedTimeout: DWORD;
    TransmissionRetryTimeout: DWORD;
  end;



Ты тут где-то видишь размер структуры в первом поле ?
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509432
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi,

конкретно тут - нет.

кстати record без указания выравнивания, без спецификатора packed....

изменится компилятор - и может поехать структура.

или например переход с Win32 API и Delphi ANSI->UTF16
или Win32 -> Win64

в общем, если есть возможность у Windows динамически запросить "сколько тебе памяти надо" - то это и нужно делать, а не хардкодить sizeof или вообще магические константы
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509436
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochDelphi ANSI->UTF16Для этой структуры размер не изменится
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509441
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Для этой структуры

вот вот, для ЭТОЙ

чем проверять каждую структуру с риском забыть или ошибиться, лучше использовать один общий принцип

-----------

ну а вообще, это оффтопик зверский.

Повторяю, исходная ошибка исходного автора в том, что он:

1) не проверяет результаты работы функций (возвращаемое значение)

2) ошибку от первой функции переводит в исключение не сразу, а только после вызова второй функции, чем запутал и себя и нас :-)
...
Рейтинг: 0 / 0
Получение информации _PRINTER_INFO_5 о принтере
    #39509453
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochschi,

конкретно тут - нет.

кстати record без указания выравнивания, без спецификатора packed....

изменится компилятор - и может поехать структура.


Никуда она не поедет :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Получение информации _PRINTER_INFO_5 о принтере
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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