vb.net LPT端口 开钱箱和小票纸打印超时问题解决办法

这篇博客介绍了如何使用VB.NET和C#编程语言通过DllImport调用kernel32.dll来操作LPT端口,设置超时时间和发送数据。代码示例展示了字节方式和流方式两种发送数据的方法,字节方式无法触发异常,而流方式在超时时可以捕获异常。博主强调测试时可模拟打印机缺纸状态以观察超时效果,并提示注意编码适应性。
摘要由CSDN通过智能技术生成

LPT端口默认超时为五分钟。往此端口写一条数据,就是超时五分钟。n条就是5*n分钟。

往LPT端口发数据可以以字节方式发送,也可以以流的方式发送。其中以字节方式发送,超时时不会触发异常,而流的方式可以。捕获此异常,可以得到“打印机缺纸”的错误。

因为是测试,所以代码比较乱。重在理解。

字节方式(设置超时时长精准,但无法触发异常):

Public Class Form1

	<DllImport("kernel32.dll")>
	Private Shared Function CreateFile(
			ByVal lpFileName As String,
			ByVal dwDesiredAccess As Integer,
			ByVal dwShareMode As Integer,
			ByVal lpSecurityAttributes As Integer,
			ByVal dwCreationDisposition As Integer,
			ByVal dwFlagsAndAttributes As Integer,
			ByVal hTemplateFile As Integer
		) As Integer
	End Function

	<DllImport("kernel32.dll")>
	Private Shared Function CloseHandle(ByVal hObject As Integer) As Integer
	End Function

	<DllImport("kernel32.dll")>
	Private Shared Function GetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
	End Function

	<DllImport("kernel32.dll")>
	Private Shared Function SetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
	End Function
	Private Structure COMMTIMEOUTS
		Public ReadIntervalTimeout As Long
		Public ReadTotalTimeoutMultiplier As Long
		Public ReadTotalTimeoutConstant As Long
		Public WriteTotalTimeoutMultiplier As Long
		Public WriteTotalTimeoutConstant As Long
	End Structure

	<DllImport("kernel32.dll")>
	Private Shared Function WriteFile(
		ByVal hFile As Integer,
		ByVal Buffer As Byte(),
		ByVal nNumberOfBytesToWrite As Integer,
		ByRef lpNumberOfBytesWritten As Integer,
		ByRef lpOverlapped As OVERLAPPED
		) As Integer
	End Function


	<StructLayout(LayoutKind.Sequential)>
	Private Structure OVERLAPPED
		Public ternal As Integer
		Public ternalHigh As Integer
		Public offset As Integer
		Public OffsetHigh As Integer
		Public hEvent As Integer
	End Structure

	Public Const GENERIC_READ As Long = &H80000000
	Public Const GENERIC_WRITE As UInteger = &H40000000
	Public Const OPEN_EXISTING As UInteger = 3

	Private Shared _opened As Boolean = False
	Private Shared _handle As IntPtr = -1
	Public Shared Property Port() As String = "LPT1"

	Dim ntime As COMMTIMEOUTS

	Private Sub setTimeout()
		_handle = CreateFile(Port, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
		ntime.ReadIntervalTimeout = 5000
		ntime.ReadIntervalTimeout = 5000
		ntime.ReadTotalTimeoutConstant = 5000
		ntime.ReadTotalTimeoutMultiplier = 5000
		ntime.WriteTotalTimeoutConstant = 5000
		ntime.WriteTotalTimeoutMultiplier = 5000
		SetCommTimeouts(_handle, ntime)
		Close()
	End Sub

	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
		setTimeout()
		OpenBox()
	End Sub

	Public Shared Sub WriteByte(ByVal data() As Byte)
		If _opened Then
			WriteFile(_handle, data, data.Length, data.Length, New OVERLAPPED)
		End If
	End Sub

	Public Shared Sub Write_string(ByVal sData As String)
		Dim bytes() As Byte = System.Text.Encoding.Default.GetBytes(sData)
		WriteByte(bytes)
	End Sub

	Public Sub OpenBox()
		OpenLPT()
		MsgBox(1)
		Write_string(Chr(27) & Chr(112) & Chr(0) & Chr(13) & Chr(10))  '开钱箱
		Close()
		MsgBox(2)
	End Sub

	Public Sub OpenLPT()
		If _opened = False Then
			_handle = CreateFile(Port, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
			If _handle = -1 Then
				MsgBox("打开并口失败")
				Exit Sub
			End If
			_opened = True
		End If
	End Sub

	Public Sub Close()
		If _handle <> -1 Then
			CloseHandle(_handle)
			_handle = -1
		End If
		_opened = False
	End Sub
End Class

流方式(好像实际超时时长要比设置的超时时长多一倍):

Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1

	<DllImport("kernel32.dll")>
	Private Shared Function CreateFile(
			ByVal lpFileName As String,
			ByVal dwDesiredAccess As Integer,
			ByVal dwShareMode As Integer,
			ByVal lpSecurityAttributes As Integer,
			ByVal dwCreationDisposition As Integer,
			ByVal dwFlagsAndAttributes As Integer,
			ByVal hTemplateFile As Integer
		) As Integer
	End Function

	<DllImport("kernel32.dll")>
	Private Shared Function CloseHandle(ByVal hObject As Integer) As Integer
	End Function

	<DllImport("kernel32.dll")>
	Private Shared Function GetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
	End Function


	<DllImport("kernel32.dll")>
	Private Shared Function SetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
	End Function

	Private Structure COMMTIMEOUTS
		Public ReadIntervalTimeout As Long
		Public ReadTotalTimeoutMultiplier As Long
		Public ReadTotalTimeoutConstant As Long
		Public WriteTotalTimeoutMultiplier As Long
		Public WriteTotalTimeoutConstant As Long
	End Structure

	Public Const FILE_ATTRIBUTE_NORMAL As Short = &H80
	Public Const INVALID_HANDLE_VALUE As Short = -1
	Public Const GENERIC_READ As Long = &H80000000
	Public Const GENERIC_WRITE As UInteger = &H40000000
	Public Const CREATE_NEW As UInteger = 1
	Public Const CREATE_ALWAYS As UInteger = 2
	Public Const OPEN_EXISTING As UInteger = 3

	Private Shared _opened As Boolean = False
	Private Shared _handle As IntPtr = -1
	Public Shared Property Port() As String = "LPT1"

	Dim ntime As COMMTIMEOUTS
	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

		_handle = CreateFile(Port, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
		ntime.ReadIntervalTimeout = 2000
		ntime.ReadIntervalTimeout = 2000
		ntime.ReadTotalTimeoutConstant = 2000
		ntime.ReadTotalTimeoutMultiplier = 2000
		ntime.WriteTotalTimeoutConstant = 2000
		ntime.WriteTotalTimeoutMultiplier = 2000
		SetCommTimeouts(_handle, ntime)
		Close()
		OpenBox()
	End Sub
'开钱箱
	Public Sub OpenBox()
		OpenLPT()
		If _opened = False Then
			MsgBox("LPT未打开")
			Exit Sub
		End If
		MsgBox(1)
		Try
			Dim fs As FileStream = New FileStream(_handle, FileAccess.Write)
			Dim sw As StreamWriter = New StreamWriter(fs, System.Text.Encoding.Default)
			sw.Write(Chr(27) & Chr(112) & Chr(0) & Chr(13) & Chr(10))
			sw.Close()
			fs.Close()
		Catch ex As Exception
			MsgBox("exex:" & ex.Message)
		End Try
		Close()
		MsgBox(2)
	End Sub

	'打印小票
	Public Function Write(ByVal sData As String) As Boolean
		setTimeout2()
		If _opened = False Then
			_handle = CreateFile(Port, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
			If _handle = -1 Then
				LastError = ("打不开端口,重启电脑再试一次吧")
				Return False
			End If
		End If
		_opened = True
		Try
			Dim fs As FileStream = New FileStream(_handle, FileAccess.Write)
			Dim sw As StreamWriter = New StreamWriter(fs, System.Text.Encoding.Default)
			sw.Write(sData)
			sw.Close()
			fs.Close()
			Close()
			Return True
		Catch ex As Exception
			LastError = ex.Message
			Close()
			Return False
		End Try
	End Function
	Public Sub OpenLPT()
		If _opened = False Then
			_handle = CreateFile(Port, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
			If _handle = -1 Then
				MsgBox("打开并口失败")
				Exit Sub
			End If
			_opened = True
		End If
	End Sub

	Public Sub Close()
		If _handle <> -1 Then
			CloseHandle(_handle)
			_handle = -1
		End If
		_opened = False
	End Sub

End Class

测试的时候,把小票纸拿出来,制造一个缺纸状态。就能测试了。

注意上面发送的编码可能需要根据具体的收银机来修改一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值