vb.netvisual-studio-2010winapiprint-spooler-api

the given path's format is not supported in vb.net


I use ESC/P or Epson Standard Code for Printers which aims to make bold. But I found there was an error "the given path's format is not supported". Is there a best solution?

Thanks

the given path's format is not supported

Dim ESC As String = "\u001B"
Dim BoldOn As String = (ESC + ("E" + "\u0001"))
Dim BoldOff As String = (ESC + ("E" + "\0"))
 Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
        ' Open the file.
        Using 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(fs.Length - 1) As Byte
            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 Using
    End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim printer As String = "Generic / Text Only"
        For i As Integer = 1 To 1
            SendFileToPrinter(printer, (BoldOn + ("C:\vDos\#LPT1.asc" + BoldOff)))
'SendFileToPrinter(printer, "C:\vDos\#LPT1.asc") if I use this code then the error does not appear 
        Next i
  
    End Sub

Solution

  • Your are passing the result of (BoldOn + ("C:\vDos\#LPT1.asc" + BoldOff)) to the szFileName parameter of your method but the one and only place that parameter is being used is here:

    Using fs As New FileStream(szFileName, FileMode.Open)
    

    The prefix and suffix you're adding are creating a value that is not a valid file path as far as the FileStream constructor is concerned, hence the exception. You need to pass a valid file path to that constructor.

    It appears that that prefix and suffix are supposed to be passed to the printer somehow, but you're not doing that. My guess would be that you need to add that prefix and suffix to the actual data from the file, not the file path, e.g.

    Dim BoldOn As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\u0001"))
    Dim BoldOff As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\0"))
    
    Dim fileContents = File.ReadAllBytes(filePath)
    Dim dataToPrint = BoldOn.Concat(fileContents).Concat(BoldOff).ToArray()
    

    It appears that I need spell it out in detail, so here's your original code modified to incorporate what I explained above:

    Private Shared ESC As String = "\u001B"
    Private Shared BoldOn As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\u0001"))
    Private Shared BoldOff As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\0"))
    
    Public Shared Function SendFileToPrinter(printerName As String, filePath As String) As Boolean
        Dim bytes = BoldOn.Concat(File.ReadAllBytes(filePath)).Concat(BoldOff).ToArray()
        Dim byteCount = bytes.Length
        Dim unmanagedBytesPointer = Marshal.AllocCoTaskMem(byteCount)
    
        Marshal.Copy(bytes, 0, unmanagedBytesPointer, byteCount)
    
        Dim success = SendBytesToPrinter(printerName, unmanagedBytesPointer, byteCount)
    
        Marshal.FreeCoTaskMem(unmanagedBytesPointer)
    
        Return success
    End Function
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim printer = "Generic / Text Only"
    
        SendFileToPrinter(printer, "C:\vDos\#LPT1.asc")
    End Sub
    

    Note that it is just an educated guess that you need to combine those printer commands with the file contents. It's up to you to confirm that and, if it's not the case, find out what is required.