powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Печать из-под Network Service не работает, куда копать?
12 сообщений из 12, страница 1 из 1
Печать из-под Network Service не работает, куда копать?
    #39495131
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приложение запущено из-под Network Service.
Задача: распечатать tiff-файл на заданный принтер, и ни фига не работает.

Для теста использую Русиновича:
Код: vbnet
1.
C:\Sysinternals\PsExec.exe -i -u "nt authority\network service" cmd.exe


поясняю
whoami =nt authority\network service
-i -обеспечивает режим "рабочего стола", т.е. окна и все MsgBox выводятся (под этим аккаунтом мне на экран)

Вот такой грубо тест код:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
      'печатаем через printto на тек. принтер
      'lReturn = ShellExecute(0, "printto", in_file, CStr(Chr(34) & cur_printer & Chr(34)), 0, SW_SHOWNORMAL)
      'If lReturn <= 32 Then 'ошибка printto
      'If (ShellExecute_Net(in_file, "printto", _
      ' Chr(34) & cur_printer & Chr(34), , ProcessWindowStyle.Normal)) = False Then 'ошибка printto
      If (ShellExecute_Wait_Net(in_file, "printto", _
       Chr(34) & cur_printer & Chr(34), , ProcessWindowStyle.Normal)) = False Then 'ошибка printto
        MsgBox("Printto failed")
        'rundll32.exe shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"
        Try
          ImageView_PrintTo(IntPtr.Zero, IntPtr.Zero, _
           "/pt " & _
           Chr(34) & in_file & Chr(34) & " " & _
           Chr(34) & cur_printer & Chr(34), _
           0)
          MsgBox("ImageView_PrintTo_ok")
        Catch
          'например при отсутствии shimgvw.dll по каким-то причинам
          MsgBox(Err.Description)
        End Try
      End If



Что делает:
1) пытается исполнить "printto" через ShellExecute c параметрами cur_printer (имя принтера) для файла in_file (ext=.tif)
2) если не получилось (а на Win10 без танцев с бубном вероятность что не получится велика), то делает
ImageView_PrintTo (эквивалентно команде rundll32.exe shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4")
Код: vbnet
1.
2.
  Public Declare Unicode Function ImageView_PrintTo Lib "shimgvw.dll" Alias "ImageView_PrintToW" _
   (ByVal hwnd As IntPtr, ByVal hinst As IntPtr, ByVal lpszCmdLine As String, ByVal nCmdShow As Integer) As Integer


(API недокументирована, но гарантированно рабочая на всех OS, проверено и вымучено вдоль и поперек)
В общем суть в том что эта ImageView_PrintTo точно знает как печатать файл-картинку на заданный принтер вне зависимости от того что там наворочено в verb "printto".

под юзером работает
под System тоже

Результат этого теста под Network Service
("Printto failed")
("ImageView_PrintTo_ok") -dll то параметры съела
но печати не происходит

Следующий тест -код:
Код: vbnet
1.
2.
3.
   For Each p As String In PrinterSettings.InstalledPrinters
      MsgBox(p)
    Next


имена принтеров выводит, ну по крайней мере Network System принтеры видит.

С слову об "оригиналах"
Windows Fax and Scan
Сервис -> Параметры факса
Дополнительные параметры -> при получении факса Печать на

Ни фига эта ф-ция на Win10 не работает. Там возможно используется то же самое, может свой код вывода на печать,
но суть что не работает.

И вот в чем подвох, и куда копать?
М.б. попытаться что-то еще тестово распечатать из-под какого-то .Net кода (ну в конце концов можно и нарисовать такой код ручками наверно, tiff файл то он стандартный).
Или там беда какая общая принципиальная с печатью из под Network Service?

Или надо как-то "делегировать" задачу другому аккаунту (вопрос только какому и как грамотно реализовать, понятно что можно MailSlot-ов понавешать, ток вот на что... а если это WinServer с мульти-юзерами, да еще "до входа в систему")?

P.S. метод лечения printto на Win10
запустить "OpenWith.exe .tif" (под тем аккаунтом кот. лечить) и выбрать "Просмотр фотографий Windows".
тогда она подставит в "printto" упомянутую команду shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"
(которую я и так вызываю в лоб)
На System такая ручная пилюля прокатывает, на .NetworkService пишет нет доступа, к чему доступа нет однако неясно, картинку прикладываю (файла ".tif" естественно нет, это всего лишь хитрость чтоб установить "прога по умолчанию для .tif" для аккаунта под которым запускаем, под System повторюсь прокатывает):
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39495189
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77И вот в чем подвох, и куда копать?
М.б. попытаться что-то еще тестово распечатать из-под какого-то .Net кода (ну в конце концов можно и нарисовать такой код ручками наверно, tiff файл то он стандартный).
Или там беда какая общая принципиальная с печатью из под Network Service?
.Net Netом,
а вот такая хрень под NetworkService заработала:
Код: vbnet
1.
2.
3.
4.
    Try
      Shell_Net("rundll32", "printui.dll,PrintUIEntry /k /n " & Chr(34) & "My Printer" & Chr(34), ProcessWindowStyle.Normal)
    Catch
    End Try


(эта команда печатает тестовую страницу на "My Printer")

Значит все-таки не глобальная

Тогда вопрос:
качественный код в лоб (без использования printto или конкретного другого приложения) для распечатки указанного Tiff (GDI+/- ?) с учетом многостраничности на указанный "My Printer" сварганить реально?
Когда-то давно пытался, но забил.
Здесь готов повозиться.
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39495753
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во первых выяснил почему под Network Service не работает вот это, по крайней мере воспроизвел проблему визуально
Код: vbnet
1.
rundll32.exe shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"


Вместо прямой отправки на печать просто открываем картинку в "Программа просмотра изображений" (под Network Service через Русиновича).
Делается так:
Код: vbnet
1.
    Shell_Net("rundll32", "shimgvw.dll,ImageView_Fullscreen " & IO.Path.Combine(Application.StartupPath, "test.tif"), ProcessWindowStyle.Normal)


Открывается без проблем.
А вот дальше нажимаем "печать" в интерфейсе и начинаются траблы уже на этапе предварительного просмотра (вероятно shimgvw.dll под Network Service не имеет к чему то доступа с чем работает). Короче скрин прилагаю:
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39495770
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, а во-вторых
Тогда вопрос:
качественный код в лоб (без использования printto или конкретного другого приложения) для распечатки указанного Tiff (GDI+/- ?) с учетом многостраничности на указанный "My Printer" сварганить реально?
В общем GDIPlus и .Net-овский PrintDocument - и все OK работает под Network service.
Типа так, ф-цию PrintFile можно вызвать последовательно несколько раз (но не параллельно, т.к. я использую внешние переменные типа счетчика страниц), в моем случае - консольное приложение, кот. может последовательно распечатать файл на несколько принтеров :
Код: 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.
 Dim WithEvents pd As PrintDocument
  Dim m_mfi As cMultiFrameImage
  Dim nPage As Integer = 1 ' номер тек. страницы
  Dim isTiff As Boolean

  Private Function PrintFile(ByVal file_name As String, ByVal printer_name As String) As Boolean
    ' file_name - имя многостраничного файла для печати
    ' printer_name - имя принтера
    ' ориентация, разрешение принтера и т.п. -берется из дефолтных настроек (для данного аккаунта)

    isTiff = False
    Try
      If UCase(IO.Path.GetExtension(file_name)) = ".TIF" Then isTiff = True
    Catch
    End Try

    PrintFile = False 'печать не удалась
    m_mfi = New cMultiFrameImage
    m_mfi.LoadFromFile(file_name)
    If m_mfi.FrameCount > 0 Then
      pd = New PrintDocument
      Try
        nPage = 1 'тек. страница =1
        pd.PrinterSettings.PrinterName = printer_name
        pd.DocumentName = IO.Path.GetFileNameWithoutExtension(file_name) 'отображается в окне печати
        '!!!иметь ввиду, при печати в панели задач по дефолту отображается стандатный значок WinForm (под Network Service пофиг)
        pd.Print()
        PrintFile = True 'печать удалась
      Catch ex As Exception
        'Debug.Print("Failed to print the document: " & ex.ToString)
      End Try
      pd.Dispose()
    End If
    m_mfi.Clear() 'отпускаем отображаемый объект
    nPage = 1 'сбрасываем счетчик страниц
  End Function

  Private Sub pd_PrintPage(sender As Object, e As PrintPageEventArgs) Handles pd.PrintPage
    'm_mfi.Frame(nPage) - это Bitmap, nPage -тек.страница многостраничного файла
    'если не мудрить с масштабированием/позиционированием картинки, то простейший вариант:
    'e.Graphics.DrawImage(m_mfi.Frame(nPage), e.Graphics.VisibleClipBounds)

    Dim Rf As RectangleF = e.Graphics.VisibleClipBounds
    'Debug.Print(".Width=" & Rf.Width & ";.Height=" & Rf.Height)

    Dim wSource As Single = CType(m_mfi.FrameWidth(nPage), Single) 'ширина источника
    Dim hSource As Single = CType(m_mfi.FrameHeight(nPage), Single) 'высота источника
    If isTiff AndAlso IsLowQualityTiff(m_mfi.HorizontalResolution, m_mfi.VerticalResolution) Then
      hSource = hSource * 2 'tiff 204x98 сжат по высоте в 2 раза (частный случай)
    End If
    'изображение должно максимально влезть в область печати, при этом сохранить пропорциональность
    'пересчитываем эффективную область
    ReCalculateRectangle(Rf, wSource, hSource)
    'Debug.Print(".Width=" & Rf.Width & ";.Height=" & Rf.Height)

    'печатаем в эту область
    e.Graphics.DrawImage(m_mfi.Frame(nPage), Rf)

    nPage = nPage + 1
    If nPage > m_mfi.FrameCount Then 'm_mfi.FrameCount - крайняя страница
      e.HasMorePages = False
    Else
      e.HasMorePages = True
    End If
  End Sub

  Private Sub ReCalculateRectangle(ByRef RF As RectangleF, ByVal wSource As Single, ByVal hSource As Single)
    'wSource - исх. ширина источника, hSource - исх. высота источника
    Dim wDest As Single = RF.Width 'ширина прямоугольника куда надо вписать
    Dim hDest As Single = RF.Height 'высота прямоугольника, куда надо вписать

    'попытаемся вписать в ширину wDest
    'смотрим куда попадет высота при сохранении пропорций
    Dim hEff As Single = wDest * (hSource / wSource)
    If hEff > hDest Then 'не попали, вышли за нижнюю границу
      'вписываем в высоту wDest
      'вычисляем ширину эффективной области
      RF.Width = hDest * (wSource / hSource)
    Else 'ура, попали
      RF.Height = hEff 'высота эффективной области
    End If
  End Sub

  Private Function IsLowQualityTiff(ByVal HorizontalResolution As Single, _
   ByVal VerticalResolution As Single) As Boolean '204x98, он сжат по высоте вдвое
    If (HorizontalResolution > 190) And (HorizontalResolution < 210) And _
     (VerticalResolution < 110) And (VerticalResolution > 90) Then
      Return True
    Else
      Return False
    End If
  End Function



cMultiFrameImage - класс, инкапсулирующий многофреймовый bitmap, загружает документ через m_Bitmap = New Bitmap(FileName), туда можно загружать любую GdiPlus графику, т.е. не только многостраничные TIF но и bmp, jpeg, png, gif и т.п.
Класс этот тьфу-тьфу написан давно (изначально были API на VB6, я переделывал в Graphics).
Самое муторное счас было решить задачу ReCalculateRectangle - т.е. вписать картинку в область печать по высоте или ширине.
Как-то так.
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39495808
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39495810
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy, привет,
это ты к чему эту картинку?
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496386
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Antonariy, привет,
это ты к чему эту картинку?привет.
почему-то тебя напомнила.
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496388
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,
не, не похож
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496414
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Antonariy, привет,
это ты к чему эту картинку?
Это Сизиф, если что
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496452
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
это я понял что сизиф, только мой труд как бы не сизифов, ибо плоды таки приносит.
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496463
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Изопропил,
это я понял что сизиф, только мой труд как бы не сизифов, ибо плоды таки приносит.

Так и у Сизифа так сказать, тоже плоды труда есть: камень таки катится.
Так и лопатой можно море вырыть.

https://www.power-print.net/features
...
Рейтинг: 0 / 0
Печать из-под Network Service не работает, куда копать?
    #39496663
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Antonariy,
не, не похожу тебя пивной живот? :)
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Печать из-под Network Service не работает, куда копать?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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