У меня есть приложение .NET 8 /c# Консольное приложение, которое печатает метки с использованием принтера TSC TTP-225 через команды RAW. При первом исполнении печатная метка имеет неверные координаты, вызывая смещение. Однако, если я немедленно запускаю приложение снова, метка отлично напечатает без каких -либо проблем.
симптомы
При первом пробеге:
- Текст и положения штрих -положения не совсем. /> < /ul>
В последующих прогонах: < /p>
Правильно отпечатки метки с правильным выравниванием и координатами.Screenshot showing problem:Код: Выделить всё
var command = ""; command += "SIZE 43 mm, 25 mm\r\n"; command += "GAP 2 mm, 0 mm\r\n"; command += "DIRECTION 1,0\r\n"; command += "CLS\r\n"; command += "TEXT 10,25,\"FONT005\",0,1,1,\"S04-19-8948589-46\"\r\n"; command += "BARCODE 1,70,\"EAN13\",60,0,0,3,3,0,\"3200000004634\"\r\n"; command += "TEXT 90,145,\"FONT005\",0,1,1,\"46042081\"\r\n"; command += "TEXT -30,180,\"FONT005\",0,1,1,\"п.4 ч.1 ст.46\"\r\n"; command += "TEXT 165,180,\"FONT005\",0,1,1,\"27.12.2023\"\r\n"; command += "PRINT 1,1\r\n"; PrinterHelper.SendStringToPrinter("TSC TTP-225", command); < /code> Полный код: < /p> using Lib.Logging; using Microsoft.Extensions.DependencyInjection; using Serilog; using System.Diagnostics; using System.Runtime.InteropServices; System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); var services = new ServiceCollection(); services.AddMyLogger(options => { options.LogTargets = LogTarget.Console | LogTarget.File | LogTarget.Json; options.UseSerilogRequestLogging = false; }); try { Log.Information("Console application started"); var stopwatch = new Stopwatch(); stopwatch.Start(); services.AddSingleton(); var provider = services.BuildServiceProvider(); var businessLogic = provider.GetRequiredService(); try { await businessLogic.PrintAsync(); } catch (Exception ex) { Log.Error(ex, "PrintAsync method failed"); } stopwatch.Stop(); Log.Information("All subtasks completed, elapsed time: {Elapsed}", stopwatch.Elapsed); } catch (Exception exception) { Log.Error(exception, "Application terminated with error"); } Log.Information("Press any key to exit ......"); Console.ReadKey(); return; public class PrinterLogic { public async Task PrintAsync() { var command = ""; // Printer initialization and calibration command += "SIZE 43 mm, 25 mm\r\n"; command += "GAP 2 mm, 0 mm\r\n"; //Rotation / mirroring command += "DIRECTION 1,0\r\n"; // Clear buffer command += "CLS\r\n"; // Content (FONT005 is a custom font that has been previously downloaded (uploaded) to the printer’s memory.) command += "TEXT 10,25,\"FONT005\",0,1,1,\"S04-19-8948589-46\"\r\n"; command += "BARCODE 1,70,\"EAN13\",60,0,0,3,3,0,\"3200000004634\"\r\n"; command += "TEXT 90,145,\"FONT005\",0,1,1,\"46042081\"\r\n"; command += "TEXT -30,180,\"FONT005\",0,1,1,\"п.4 ч.1 ст.46\"\r\n"; command += "TEXT 165,180,\"FONT005\",0,1,1,\"27.12.2023\"\r\n"; // Print command += "PRINT 1,1\r\n"; Log.Information("Sending commands to printer: {{Commands}}", command); var success = PrinterHelper.SendStringToPrinter("TSC TTP-225", command); if (success) { Log.Information("Commands successfully sent to printer"); // Short pause to allow printer to process commands await Task.Delay(500); } else { Log.Error("Failed to send commands to printer"); } } } public class PrinterHelper { // Structure and API declarions: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); // 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 static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "TSC Label Print Job"; di.pDataType = "RAW"; try { // Open the printer if (!OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { dwError = Marshal.GetLastWin32Error(); Log.Error($"Failed to open printer '{szPrinterName}'. Error code: {dwError}"); return false; } // Start document if (!StartDocPrinter(hPrinter, 1, di)) { dwError = Marshal.GetLastWin32Error(); Log.Error($"Failed to start print document. Error code: {dwError}"); return false; } // Start page if (!StartPagePrinter(hPrinter)) { dwError = Marshal.GetLastWin32Error(); Log.Error($"Failed to start print page. Error code: {dwError}"); EndDocPrinter(hPrinter); return false; } // Send data bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); if (!bSuccess) { dwError = Marshal.GetLastWin32Error(); Log.Error($"Error writing data to printer. Error code: {dwError}"); } else if (dwWritten != dwCount) { Log.Warning($"Wrote {dwWritten} bytes out of {dwCount} during sticker print"); } // End page EndPagePrinter(hPrinter); // End document EndDocPrinter(hPrinter); } catch (Exception ex) { Log.Error(ex, "Exception while sending data to printer"); bSuccess = false; } finally { // Close printer if (hPrinter != IntPtr.Zero) { ClosePrinter(hPrinter); } } return bSuccess; } public static bool SendStringToPrinter(string szPrinterName, string szString) { if (string.IsNullOrEmpty(szString)) { Log.Warning("Attempt to send empty string to printer"); return false; } if (string.IsNullOrEmpty(szPrinterName)) { Log.Error("Printer name not specified"); return false; } var pBytes = IntPtr.Zero; bool result; try { // Convert string to ANSI for TSC printer pBytes = Marshal.StringToCoTaskMemAnsi(szString); var dwCount = szString.Length; result = SendBytesToPrinter(szPrinterName, pBytes, dwCount); } catch (Exception ex) { Log.Error(ex, "Error preparing data for printer"); result = false; } finally { // Free memory if (pBytes != IntPtr.Zero) { Marshal.FreeCoTaskMem(pBytes); } } return result; } }

My attempts to fix this problem:
Added delays before sending commands (до 500 мс) < /li>
Проверенные команды инициализации принтера (, gap , cls )Код: Выделить всё
SIZE - Обеспечить, чтобы буфер принтера очищается перед каждой печатной
Язык /Платформа: .net 8, C#, Windows < /li>
Метод связи: Raw Thancs через Win32 API (
Код: Выделить всё
winspool.drvUpdate:
Based on the suggestions in the comments:
- I moved the CLS command to the very beginning of the command sequence to ensure the buffer is cleared before any other commands.
- The printer был включен и простаивал перед тестом. С момента питания ничего не было напечатано. any errors.

Подробнее здесь: https://stackoverflow.com/questions/797 ... onsole-app