修复提交

This commit is contained in:
2025-04-22 15:26:25 +08:00
parent daf69f6a9d
commit 555ce4c4fb
29 changed files with 1376 additions and 1 deletions

View File

@@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using BarTender;
namespace linesider_screen_tool
{
public class BartenderPrintHelper : IDisposable
{
private Application _btApp;
private Format _btFormat;
private bool _disposed = false;
/// <summary>
/// 初始化 Bartender 应用程序
/// </summary>
public BartenderPrintHelper()
{
try
{
_btApp = new Application();
}
catch (Exception ex)
{
throw new Exception("无法初始化 Bartender 应用程序。请确保 BarTender 已安装。", ex);
}
}
/// <summary>
/// 打印标签
/// </summary>
/// <param name="templatePath">标签模板路径</param>
/// <param name="subStringValues">标签变量键值对</param>
/// <param name="copies">打印份数</param>
/// <param name="serializedLabels">序列化标签数量</param>
/// <returns>是否打印成功</returns>
public bool PrintLabel(string templatePath, Dictionary<string, string> subStringValues, int copies = 1, int serializedLabels = 1)
{
if (_disposed)
throw new ObjectDisposedException("BartenderPrintHelper", "对象已被释放,不能执行打印操作。");
try
{
Console.WriteLine("正在启动 BarTender...");
// 2. 创建 BarTender 应用实例
var btApp = new Application();
// 3. 设置可见性(调试时建议开启)
// btApp.Visible = false; // 设置为 true 可以看到 BarTender 界面
Console.WriteLine("BarTender 启动成功!");
// 4. 打开模板文件
Console.WriteLine($"正在打开模板: {templatePath}");
Format btFormat = btApp.Formats.Open(templatePath);
Console.WriteLine("模板加载成功!");
// 5. 设置打印份数
btFormat.PrintSetup.NumberSerializedLabels = 1;
// 6. 设置变量值(添加日志输出)
Console.WriteLine("正在设置变量值...");
foreach (var a in subStringValues)
{
btFormat.SetNamedSubStringValue(a.Key, a.Value);
}
// 8. 执行打印
Console.WriteLine("正在发送打印任务...");
btFormat.PrintOut(false, false); // 不显示对话框,不等待打印完成
Console.WriteLine("打印任务已发送!");
// 9. 关闭模板
btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
return true;
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// 清理托管资源
}
// 清理非托管资源
if (_btFormat != null)
{
_btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btFormat);
_btFormat = null;
}
if (_btApp != null)
{
_btApp.Quit(BtSaveOptions.btDoNotSaveChanges);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btApp);
_btApp = null;
}
_disposed = true;
}
}
/// <summary>
/// 批量打印多个List标签
/// </summary>
/// <param name="templatePath">标签模板路径</param>
/// <param name="items">包含多个标签数据的列表</param>
/// <param name="copiesPerItem">每个标签的打印份数</param>
/// <param name="serializedLabels">序列化标签数量</param>
/// <param name="getSubStringValues">从列表项获取标签变量的委托</param>
/// <returns>是否全部打印成功</returns>
public bool PrintLabels<T>(
string templatePath,
List<T> items,
int copiesPerItem = 1,
int serializedLabels = 1,
Func<T, Dictionary<string, string>> getSubStringValues = null)
{
if (_disposed)
throw new ObjectDisposedException("BartenderPrintHelper", "对象已被释放,不能执行打印操作。");
if (items == null || items.Count == 0)
return false;
try
{
// 打开标签模板
_btFormat = _btApp.Formats.Open(templatePath);
// 设置打印参数
_btFormat.PrintSetup.IdenticalCopiesOfLabel = copiesPerItem;
_btFormat.PrintSetup.NumberSerializedLabels = serializedLabels;
bool allSuccess = true;
// 遍历所有项目并打印
foreach (var item in items)
{
try
{
// 获取当前项的变量值
var subStringValues = getSubStringValues?.Invoke(item);
// 设置标签变量值
if (subStringValues != null)
{
foreach (var kvp in subStringValues)
{
_btFormat.SetNamedSubStringValue(kvp.Key, kvp.Value);
}
}
// 执行打印
_btFormat.PrintOut(false, false);
}
catch (Exception ex)
{
// 记录错误但继续打印其他项
allSuccess = false;
// 可以在这里添加日志记录
Console.WriteLine($"打印标签时出错: {ex.Message}");
}
}
return allSuccess;
}
catch (Exception ex)
{
throw new Exception($"批量打印标签时出错: {ex.Message}", ex);
}
finally
{
if (_btFormat != null)
{
_btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btFormat);
_btFormat = null;
}
}
}
/// <summary>
/// 批量打印多个标签(新增方法)
/// </summary>
/// <param name="templatePath">标签模板路径</param>
/// <param name="batchSubStringValues">多个标签的变量键值对列表</param>
/// <param name="copiesPerLabel">每个标签的打印份数</param>
/// <param name="serializedLabels">序列化标签数量</param>
/// <returns>是否全部打印成功</returns>
public bool PrintBatchLabels(
string templatePath,
List<Dictionary<string, string>> batchSubStringValues,
int copiesPerLabel = 1,
int serializedLabels = 1)
{
if (_disposed)
throw new ObjectDisposedException(nameof(BartenderPrintHelper), "对象已被释放,不能执行打印操作。");
if (batchSubStringValues == null || batchSubStringValues.Count == 0)
return false;
try
{
// 打开标签模板(只打开一次,提升性能)
_btFormat = _btApp.Formats.Open(templatePath);
_btFormat.PrintSetup.IdenticalCopiesOfLabel = copiesPerLabel;
_btFormat.PrintSetup.NumberSerializedLabels = serializedLabels;
bool allSuccess = true;
// 遍历所有标签数据并打印
foreach (var subStringValues in batchSubStringValues)
{
try
{
// 设置变量值
foreach (var kvp in subStringValues)
{
_btFormat.SetNamedSubStringValue(kvp.Key, kvp.Value);
}
// 执行打印(不关闭模板,继续复用)
_btFormat.PrintOut(false, false);
}
catch (Exception ex)
{
allSuccess = false;
// 可记录日志或抛出特定异常
Console.WriteLine($"打印标签时出错: {ex.Message}");
}
}
return allSuccess;
}
catch (Exception ex)
{
throw new Exception($"批量打印标签时出错: {ex.Message}", ex);
}
finally
{
// 确保释放资源
if (_btFormat != null)
{
_btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btFormat);
_btFormat = null;
}
}
}
~BartenderPrintHelper()
{
Dispose(false);
}
}
}

View File

@@ -0,0 +1,172 @@

using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Formatter;
using MQTTnet.Protocol;
using System;
using System.Collections.Concurrent;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace linesider_screen_tool
{
public class MQTTHepler
{
public IMqttClient _mqttClient;
private MqttClientOptions _options;
private readonly string _clientId;
private readonly string _server;
private readonly int _port;
private readonly string _username;
private readonly string _password;
private readonly bool _cleanSession;
/// <summary>
/// 初始化 MQTT 客户端
/// </summary>
public MQTTHepler(string server, int port = 1883, string clientId = null,
string username = null, string password = null, bool cleanSession = true)
{
_server = server;
_port = port;
_clientId = clientId;
_username = username;
_password = password;
_cleanSession = cleanSession;
}
/// <summary>
/// 连接到 MQTT 服务器
/// </summary>
public async Task ConnectAsync()
{
if (_mqttClient != null && _mqttClient.IsConnected)
return;
var factory = new MqttFactory();
_mqttClient = factory.CreateMqttClient();
// 先注册事件处理器
//_mqttClient.ApplicationMessageReceivedAsync += HandleReceivedApplicationMessage;
var builder = new MqttClientOptionsBuilder()
.WithTcpServer(_server, _port)
.WithClientId(_clientId) // 确保指定了 ClientId
.WithCleanSession(_cleanSession);
if (!string.IsNullOrEmpty(_username))
builder.WithCredentials(_username, _password);
_options = builder.Build();
_mqttClient.DisconnectedAsync += async e =>
{
Console.WriteLine($"MQTT 断开: {e.Reason}");
await Task.Delay(5000);
await ReconnectAsync();
};
await _mqttClient.ConnectAsync(_options, CancellationToken.None);
Console.WriteLine("MQTT 连接成功");
}
/// <summary>
/// 订阅主题
/// </summary>
public async Task SubscribeAsync(string topic, MqttQualityOfServiceLevel qos = MqttQualityOfServiceLevel.AtLeastOnce)
{
if (_mqttClient == null || !_mqttClient.IsConnected)
await ConnectAsync();
var topicFilter = new MqttTopicFilterBuilder()
.WithTopic(topic)
.WithQualityOfServiceLevel(qos)
.Build();
var result = await _mqttClient.SubscribeAsync(topicFilter, CancellationToken.None);
Console.WriteLine($"订阅结果: {result.Items.First().ResultCode}");
}
/// <summary>
/// 发布消息
/// </summary>
public async Task PublishAsync(string topic, string payload,MqttQualityOfServiceLevel qos = MqttQualityOfServiceLevel.AtLeastOnce,
bool retain = false)
{
if (_mqttClient == null || !_mqttClient.IsConnected)
await ConnectAsync();
var message = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(qos)
.WithRetainFlag(retain)
.Build();
try
{
await _mqttClient.PublishAsync(message, CancellationToken.None);
Console.WriteLine($"已发布消息到主题 {topic}: {payload}");
}
catch (Exception ex)
{
Console.WriteLine($"发布消息失败: {ex.Message}");
throw;
}
}
/// <summary>
/// 取消订阅主题
/// </summary>
public async Task UnsubscribeAsync(string topic)
{
if (_mqttClient == null || !_mqttClient.IsConnected)
return;
try
{
await _mqttClient.UnsubscribeAsync(topic, CancellationToken.None);
Console.WriteLine($"已取消订阅主题: {topic}");
}
catch (Exception ex)
{
Console.WriteLine($"取消订阅主题失败: {ex.Message}");
throw;
}
}
private async Task ReconnectAsync()
{
try
{
await _mqttClient.ConnectAsync(_options, CancellationToken.None);
Console.WriteLine("MQTT 重新连接成功");
}
catch (Exception ex)
{
Console.WriteLine($"MQTT 重新连接失败: {ex.Message}");
}
}
public async Task DisconnectAsync()
{
if (_mqttClient == null || !_mqttClient.IsConnected)
return;
try
{
await _mqttClient.DisconnectAsync();
DisconnectAsync().Wait();
_mqttClient?.Dispose();
GC.SuppressFinalize(this);
Console.WriteLine("MQTT 已断开连接");
}
catch (Exception ex)
{
Console.WriteLine($"断开连接失败: {ex.Message}");
}
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Text.RegularExpressions;
using MQTTnet;
using Newtonsoft.Json;
namespace linesider_screen_tool
{
public class SerialPortHepler:IDisposable
{
private SerialPort _serialPort;
// 内部缓冲区用于存储接收到的数据
private StringBuilder receiveBuffer = new StringBuilder();
public event Action<string> DataReceived;
public SerialPortHepler(string portName,int baudRaate,int parity,int dataBits,int stopBits)
{
_serialPort = new SerialPort(portName, baudRaate, (Parity)parity, dataBits, (StopBits)stopBits);
}
public async void Open()
{
if (_serialPort != null && _serialPort.IsOpen)
{
return;
}
try
{
_serialPort.Open();
_serialPort.DataReceived += SerialPort_DataReceived;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void Close()
{
if (_serialPort == null || !_serialPort.IsOpen)
{
return;
}
try
{
_serialPort.DataReceived -= SerialPort_DataReceived;
_serialPort.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string newData = _serialPort.ReadExisting();
receiveBuffer.Append(newData);
// 处理缓冲区中的数据
string bufferContent = receiveBuffer.ToString();
string[] lines = Regex.Split(bufferContent, @"\r\n|\n|\r", RegexOptions.None);
for (int i = 0; i < lines.Length - 1; i++)
{
string line = lines[i].Trim();
if (!string.IsNullOrEmpty(line))
DataReceived.Invoke(line); ;
}
// 将最后一行保留到缓冲区中
receiveBuffer.Clear();
if (lines.Length > 0)
{
receiveBuffer.Append(lines[lines.Length - 1]);
}
}
public void Dispose()
{
Close();
_serialPort?.Dispose();
_serialPort = null;
}
}
}