0

how to auto detect printer data update and without event button. and if I use the event button and I continue to process it once again then the process cannot be done because it is used by other processes such as the screenshot I attached below. when the printer data is updated, it automatically prints. There may be the best solution.

thanks

warning cannot access

path printer data : "C:\vDos"
file name printer data : #LPT1.asc
 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(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 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;
        dwCount = (szString.Length + 1) * Marshal.SystemMaxDBCSCharSize

        ' 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 buttonSEND_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonSEND.Click
        'Dim open As New System.Windows.Forms.OpenFileDialog()
        'Dim szFileName As String = "C:\vDos\#LPT1.asc"
        'If open.ShowDialog().Equals(DialogResult.OK) Then
        '    Dim sr As New StreamReader(open.FileName)
        '    szFileName = sr.ReadToEnd()
        '    sr.Close()
        'End If
        Dim printer As String = "Generic / Text Only"

        For i As Integer = 1 To 1
            SendFileToPrinter(printer, "C:\vDos\#LPT1.asc")
        Next i

    End Sub
roy
  • 693
  • 2
  • 11
  • 1
    `FileStream` and `BinaryReader` are disposable objects. Hence you need to dispose of these objects Better if you declare them with a `Using` statement, so there's a very good chance they're disposed even when an exception is generated in the meanwhile. -- Disposing of disposable objects is not exactly *optional*. – Jimi Jul 24 '22 at 13:12
  • @Jimi ,where should I put the code `using` – roy Jul 24 '22 at 13:22
  • `Using fs As New FileStream(szFileName, FileMode.Open), br As New BinaryReader(fs) ' All the rest End Using` – Jimi Jul 24 '22 at 13:25
  • @Jimi , it went perfectly I did the button event once again not making an error. If I don't use the event button, is it possible that it can be done – roy Jul 24 '22 at 13:34
  • I'm not sure what that means. `SendFileToPrinter()` and `SendStringToPrinter()` are methods, you can call these methods as you please, whenever required. The `Click` handler of a Button is just a method as any other. I don't know what *when the printer data is updated* implies, in your code, but this of course happens inside a method... (it could also be a Property Setter, still a method) – Jimi Jul 24 '22 at 13:38
  • @jimi ,I tried using `Form1_Load` this can be done but can it form auto close after sending the file to the printer. I use the code with ` – roy Jul 24 '22 at 13:46
  • I don't know why you need to show a Form to send data to a Printer or a File. Is `Form1` the only Form in your app (the starting Form)? Or just another Form? In that case, you could simply send the data to the Printer or File instead of calling `Form1.Show()`. -- If you really have to load that Form, just call `Me.Close()` in the `Load` handler after you have generated the print output. – Jimi Jul 24 '22 at 13:53
  • @Jimi , this is just a print helper app, if I use `Form1_Load` and `Me.Close()` I tried to print with different invoice numbers at the time can only generate 1 prn file only this is because there is a code statement `Me.Close()` – roy Jul 24 '22 at 14:38
  • @Jimi , or also because the form load is not too fast – roy Jul 24 '22 at 14:41
  • @Jimi , form1 is just another Form – roy Jul 24 '22 at 14:49
  • @jimi , so I use form1 as the print helper of the dos program – roy Jul 24 '22 at 14:53
  • Well, you don't need a Form to print stuff. Instead of calling `Form.Show()`, just call your printing procedure (I assume `SendBytesToPrinter()` uses `OpenPrinter()` / `StartDocPrinter()` / `WritePrinter()` / `EndDocPrinter()`, so just PInvoking Win32 functions) -- It looks like you don't show a print preview, so what's this Form for? What is a *DOS program*? Do you mean a Console app? – Jimi Jul 24 '22 at 14:57
  • @jimi , is it if without show form is there a solution ? – roy Jul 24 '22 at 14:59
  • I don't know what that means. – Jimi Jul 24 '22 at 15:01
  • @jimi , i'm using a dos emulator i.e. vdos. but in the future I need to print preview maybe .`Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean` . the function you're referring to is already in my code – roy Jul 24 '22 at 15:03
  • @Jimi , `so what's this Form for?` to help printer data to the printer and `Do you mean a Console app?` I'm not interested in the console app because I want to use it for winform because my plan later there will be a checkbox that will display the print preview – roy Jul 24 '22 at 15:09
  • Well, I can only help with the code you have posted. -- If you're calling the Win32 functions mentioned, those are all synchronous. All method calls should return after a File has already been printed. I have no idea what code you have written to print multiple files, for now you have `For i As Integer = 1 To 1`; if you write `For i As Integer = 1 To 10` and print all files from, say, the Form's Constructor (`Public Sub new()`), then call `Me.Close()` in `Form.Load`, it should be ok. If it doesn't work, post a new question showing what code you have written for this. – Jimi Jul 24 '22 at 15:12
  • @Jimi , `For i As Integer = 1 To 10` if I use the code in the printer "Generic / Text Only" then make the prn file into 10 files – roy Jul 25 '22 at 09:43
  • @Jimi , [link](https://stackoverflow.com/questions/73109469/how-to-use-win32-functions-for-multi-print-in-vb-net) . here's a new question link – roy Jul 25 '22 at 12:51

0 Answers0