How to use API calls in VS2005 for printing

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



I have this code in a class, works fine in VS2003 but not in VS2005,
somebody help me! The error said "PInvokeStackInbalance" in OpenPrinter.

Imports System.IO
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices

Public Class RawPrinterHelper
Shared xDocumentName As String = "XXX"
Public WriteOnly Property _DocumentName() As String
Set(ByVal Value As String)
xDocumentName = Value
End Set
End Property
' Structure and API declarions:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure DOCINFOW
<MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
End Structure

<DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter
As IntPtr, ByVal pd As Long) As Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal
level As Int32, ByRef pDI As DOCINFOW) As Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As
Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As
Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As
Boolean
End Function

<DllImport("winspool.Drv", EntryPoint:="WritePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal
pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As
Boolean
End Function

Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String,
ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
Dim hPrinter As IntPtr ' The printer handle.
Dim dwError As Int32 ' Last error - in case there was
trouble.
Dim di As DOCINFOW ' Describes your document (name, port,
data type).
Dim dwWritten As Int32 ' The number of bytes written by
WritePrinter().
Dim bSuccess As Boolean ' Your success code.

' Set up the DOCINFO structure.
With di
.pDocName = xDocumentName
.pDataType = "RAW"
End With
' Assume failure unless you specifically succeed.
bSuccess = False
If OpenPrinter(szPrinterName, hPrinter, 0) Then
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
' Write your printer-specific bytes to the printer.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount,
dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
End If
' 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 ' SendBytesToPrinter()

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 large enough to hold the file's contents.
Dim bytes(fs.Length) As Byte
Dim bSuccess As Boolean
' Your unmanaged pointer
Dim pUnmanagedBytes As IntPtr
bytes = br.ReadBytes(fs.Length)
pUnmanagedBytes = Marshal.AllocCoTaskMem(fs.Length)
Marshal.Copy(bytes, 0, pUnmanagedBytes, fs.Length)
' Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes,
fs.Length)
' Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes)
fs.Close()
fs = Nothing
Return bSuccess
End Function ' SendFileToPrinter()

Public Shared Function SendStringToPrinter(ByVal szPrinterName As
String, ByVal szString As String)
Dim pBytes As IntPtr
Dim dwCount As Int32
dwCount = szString.Length()
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
SendBytesToPrinter(szPrinterName, pBytes, dwCount)
Marshal.FreeCoTaskMem(pBytes)
End Function
End Class


.



Relevant Pages

  • VirtualAllocEx returns a bad pointer in some processes
    ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
    (microsoft.public.vc.mfc)
  • Virtual memory C++ problem
    ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
    (microsoft.public.win32.programmer.kernel)
  • Re: zebra Printer
    ... Public pOutputFile As String ... Public Shared Function ClosePrinterAs ... Dim ByteBuf As Integer ... Public Function GetPrinterStatusText(ByVal PI2Status As Long) As ...
    (microsoft.public.dotnet.languages.vb)
  • SetPrinter for network printers
    ... Public dmDeviceName As String ... Public pSecurityDescriptor As IntPtr ... Dim pPrinterInfo As IntPtr ...
    (microsoft.public.dotnet.languages.vb)
  • Re: MapiSendMail and web browser
    ... Public Shared Function SendMail(ByVal strAttachmentFileName As String, ... Dim winhandle As IntPtr = New IntPtr ... Public Class MapiMessage ...
    (microsoft.public.win32.programmer.messaging)