GetCommTimeouts возвращает ошибку 87 для сетевого принтера - PullRequest
0 голосов
/ 29 октября 2019

Для связи с принтерами мы используем методы и дескрипторы WinApi. Наше решение правильно работало на Windows 7 (32- и 64-разрядные версии). В настоящее время мы переходим на Windows 10, и есть проблема с сетевыми принтерами.

Проблема в том, что когда мы пытаемся вызвать GetCommTimeouts, обновим их до того, что нам нужно, и вернем их обратно. С кодом ниже, если я использую прямой доступ к параллельному порту (пример пути - \\.\LPT1), я могу подключиться к принтеру. Однако на сетевом принтере (путь \\PcName\PrintersName) приведенный ниже код завершается ошибкой на GetCommTimeouts. (В данном примере это не SetCommTimeouts, но он ведет себя так же, как и GetCommTimeouts).

Сбой с кодом ошибки 87 «Параметр неверен». Но структура должна быть действительной и дескриптор установлен. Дескриптор правильный, потому что, если я пропущу функции Get / SetCommTimeouts, принтер напечатает правильно. (не входит в код)

Private Const INVALID_HANDLE_VALUE As Integer = -1

Private Const GENERIC_READ = &H80000000L
Private Const GENERIC_WRITE = &H40000000

Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2

Private Const OPEN_ALWAYS = 4

Private Const FILE_FLAG_SEQUENTIAL_SCAN = &H8000000

Sub Main()

    Dim handle = CreateFile("\\PcName\PrintersSharedName",
                            GENERIC_READ Or GENERIC_WRITE,
                            FILE_SHARE_READ Or FILE_SHARE_WRITE,
                            0,
                            OPEN_ALWAYS,
                            FILE_FLAG_SEQUENTIAL_SCAN,
                            0)

    If Not handle <> INVALID_HANDLE_VALUE Then
        Console.WriteLine("OpenDeviceHandle_Error")
        Console.ReadLine()
        Return
    End If

    Try
        Dim commTimeouts As New COMMTIMEOUTS
        Dim result = GetCommTimeouts(handle, commTimeouts)
        If result = 0 Then
            Dim exception As New Win32Exception
            If exception.NativeErrorCode = 1 Then
                Console.WriteLine("GetCommTimeouts_Correct")
            Else
                Console.WriteLine($"GetCommTimeouts_Error {exception.NativeErrorCode}")
            End If
        End If
    Finally
        CloseHandle(handle)
    End Try
    Console.ReadLine()
End Sub


<DllImport("Kernel32.dll", SetLastError:=True)>
Private Function CreateFile(lpFileName As String,
                            dwDesiredAccess As UInteger,
                            dwShareMode As UInteger,
                            lpSecurityAttributes As IntPtr,
                            dwCreationDisposition As UInteger,
                            dwFlagsAndAttributes As UInteger,
                            hTemplateFile As IntPtr) As Integer
End Function

<DllImport("Kernel32.dll", SetLastError:=True)>
Private Function GetCommTimeouts(iHandle As Integer, ByRef oCommTimeouts As COMMTIMEOUTS) As Integer
End Function

<DllImport("Kernel32.dll", SetLastError:=True)>
Private Function CloseHandle(hObject As IntPtr) As Integer
End Function

<StructLayout(LayoutKind.Sequential)>
Private Structure COMMTIMEOUTS
    Dim ReadIntervalTimeout As UInteger          ' Maximum time between read chars
    Dim ReadTotalTimeoutMultiplier As UInteger   ' Multiplier of characters
    Dim ReadTotalTimeoutConstant As UInteger     ' Constant in milliseconds
    Dim WriteTotalTimeoutMultiplier As UInteger  ' Multiplier of characters
    Dim WriteTotalTimeoutConstant As UInteger    ' Constant in milliseconds
End Structure

Этот же код работает правильно на компьютере с Windows 7, и даже этот компьютер может подключаться к общему принтеру, который подключен на компьютере с Windows 10. В Windows 10 я не могу подключиться к общему принтеру на том же компьютере через общий ресурс.

В чем я не уверен, если он не работает, потому что Win10 нужно что-то другое для локальных / общих принтеров, если это что-то, связанное с Windows 10, или если в самом коде есть какая-то ошибка. Я пробовал разные настройки параметров, несколько раз проверял интерфейсы и структуры WinApi, проверял, совпадают ли права доступа к принтеру с Win 7. Все выглядит правильно для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...