ネットから入手したこのコードを使用しています。
RAW データを取得してラベルを印刷する Intermec PM4i ラベル プリンターに txt ファイルを送信しようとしています。ドライバーをロードし、マシンにプリンターをセットアップしました。プリンターと FAX に移動してプリンターを選択し、プロパティに移動してファイルをプリンターに送信すると、ラベルが印刷されます。だから私はそれが機能することを知っています。しかし、このコードを実行すると、txt ファイルを要求するダイアログ ボックスが表示されます。ファイルを選択すると、プリンタを選択した場所で別のダイアログ ボックスが開きます。すべてが正しく機能しているようです。しかし、コードが SendBytesToPrinter() 関数に入り、OpenPrinter(szPrinterName.Normalize(), hPrinter, IntPtr.Zero) に到達すると、szPrinterName.Normalize() は正しいプリンター名を持ちます。hPrinter と IntPtr.Zero の値はどちらもゼロです。この行から、If bSuccess = False Then dwError = Marshal に直接進みます。GetLastWin32Error() End If And Marshal.GetLastWin32Error() の値は 87 です。それだけで、何も出力されません。何が起こっているのか教えてください。ありがとうございました
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1
' Structure and API declarions:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Class DOCINFOA
<MarshalAs(UnmanagedType.LPStr)> _
Public pDocName As String
<MarshalAs(UnmanagedType.LPStr)> _
Public pOutputFile As String
<MarshalAs(UnmanagedType.LPStr)> _
Public pDataType As String
End Class
<DllImport("winspool.Drv", EntryPoint:="OpenPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenPrinter(<MarshalAs(UnmanagedType.LPStr)> ByVal szPrinter As String, ByVal hPrinter As IntPtr, ByVal pd As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, <[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal di As DOCINFOA) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByVal dwWritten As Int32) As Boolean
End Function
' SendBytesToPrinter()
' When the function is given a printer name and an unmanaged array
' of bytes, the function sends those bytes to the print queue.
' Returns true on success, false on failure.
Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
Dim dwError As Int32 = 0, dwWritten As Int32 = 0
Dim hPrinter As New IntPtr(0)
Dim di As New DOCINFOA()
Dim bSuccess As Boolean = False
' Assume failure unless you specifically succeed.
di.pDocName = "My C#.NET RAW Document"
di.pDataType = "RAW"
Try
' Open the printer.
If OpenPrinter(szPrinterName.Normalize(), hPrinter, IntPtr.Zero) Then
' Start a document.
If StartDocPrinter(hPrinter, 1, di) Then
' Start a page.
If StartPagePrinter(hPrinter) Then
' Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
End If
Catch ex As Exception
MsgBox("error")
End Try
' If you did not succeed, GetLastError may give more information
' about why not.
If bSuccess = False Then
dwError = Marshal.GetLastWin32Error()
End If
Return bSuccess
End Function
Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
' Open the file.
Dim fs As New FileStream(szFileName, FileMode.Open)
' Create a BinaryReader on the file.
Dim br As New BinaryReader(fs)
' Dim an array of bytes big enough to hold the file's contents.
Dim bytes As [Byte]() = New [Byte](fs.Length - 1) {}
Dim bSuccess As Boolean = False
' Your unmanaged pointer.
Dim pUnmanagedBytes As New IntPtr(0)
Dim nLength As Integer
nLength = Convert.ToInt32(fs.Length)
' Read the contents of the file into the array.
bytes = br.ReadBytes(nLength)
' Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength)
' Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength)
' Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength)
' Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes)
Return bSuccess
End Function
Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String) As Boolean
Dim pBytes As IntPtr
Dim dwCount As Int32
' How many characters are in the string?
dwCount = szString.Length
' Assume that the printer is expecting ANSI text, and then convert
' the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
' Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount)
Marshal.FreeCoTaskMem(pBytes)
Return True
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If True Then
' Allow the user to select a file.
Dim ofd As New OpenFileDialog()
If DialogResult.OK = ofd.ShowDialog(Me) Then
' Allow the user to select a printer.
Dim pd As New PrintDialog()
pd.PrinterSettings = New PrinterSettings()
If DialogResult.OK = pd.ShowDialog(Me) Then
' Print the file to the printer.
SendFileToPrinter(pd.PrinterSettings.PrinterName, ofd.FileName)
End If
End If
End If
End Sub
End Class