将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace XP.Hardware.RaySource.Comet.Host
|
||||
{
|
||||
/// <summary>
|
||||
/// 强制退出密码输入对话框
|
||||
/// Force exit password input dialog
|
||||
/// </summary>
|
||||
internal sealed class ForceExitPasswordDialog : Form
|
||||
{
|
||||
private readonly TextBox _txtPassword;
|
||||
|
||||
/// <summary>
|
||||
/// 用户输入的密码 | The password entered by user
|
||||
/// </summary>
|
||||
public string EnteredPassword => _txtPassword.Text;
|
||||
|
||||
public ForceExitPasswordDialog()
|
||||
{
|
||||
// 窗体属性 | Form properties
|
||||
Text = "强制退出验证 | Force Exit Verification";
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ClientSize = new Size(320, 130);
|
||||
|
||||
// 提示标签 | Prompt label
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = "请输入管理员密码以强制退出:\r\nPlease enter admin password to force exit:",
|
||||
Location = new Point(12, 12),
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
// 密码输入框 | Password text box
|
||||
_txtPassword = new TextBox
|
||||
{
|
||||
Location = new Point(12, 52),
|
||||
Size = new Size(290, 23),
|
||||
UseSystemPasswordChar = true
|
||||
};
|
||||
|
||||
// 确定按钮 | OK button
|
||||
var btnOk = new Button
|
||||
{
|
||||
Text = "确定",
|
||||
DialogResult = DialogResult.OK,
|
||||
Location = new Point(146, 90),
|
||||
Size = new Size(75, 28)
|
||||
};
|
||||
|
||||
// 取消按钮 | Cancel button
|
||||
var btnCancel = new Button
|
||||
{
|
||||
Text = "取消",
|
||||
DialogResult = DialogResult.Cancel,
|
||||
Location = new Point(227, 90),
|
||||
Size = new Size(75, 28)
|
||||
};
|
||||
|
||||
AcceptButton = btnOk;
|
||||
CancelButton = btnCancel;
|
||||
Controls.AddRange(new Control[] { lbl, _txtPassword, btnOk, btnCancel });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,691 @@
|
||||
namespace XP.Hardware.RaySource.Comet.Host
|
||||
{
|
||||
partial class XplorePlaneCometHost
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_notifyIcon != null)
|
||||
{
|
||||
_notifyIcon.Visible = false;
|
||||
_notifyIcon.Dispose();
|
||||
_notifyIcon = null;
|
||||
}
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(XplorePlaneCometHost));
|
||||
this._mainLayout = new System.Windows.Forms.TableLayoutPanel();
|
||||
this._operationPanel = new System.Windows.Forms.Panel();
|
||||
this._connGroup = new System.Windows.Forms.GroupBox();
|
||||
this._lblIpAddress = new System.Windows.Forms.Label();
|
||||
this._txtIpAddress = new System.Windows.Forms.TextBox();
|
||||
this._lblPort = new System.Windows.Forms.Label();
|
||||
this._nudPort = new System.Windows.Forms.NumericUpDown();
|
||||
this._lblCpuName = new System.Windows.Forms.Label();
|
||||
this._txtCpuName = new System.Windows.Forms.TextBox();
|
||||
this._lblSourcePort = new System.Windows.Forms.Label();
|
||||
this._nudSourcePort = new System.Windows.Forms.NumericUpDown();
|
||||
this._lblStationNumber = new System.Windows.Forms.Label();
|
||||
this._nudStationNumber = new System.Windows.Forms.NumericUpDown();
|
||||
this._btnInitialize = new System.Windows.Forms.Button();
|
||||
this._btnConnectVariables = new System.Windows.Forms.Button();
|
||||
this._btnDisconnect = new System.Windows.Forms.Button();
|
||||
this._lblConnectionState = new System.Windows.Forms.Label();
|
||||
this._lblPviState = new System.Windows.Forms.Label();
|
||||
this._lblHeartbeat = new System.Windows.Forms.Label();
|
||||
this._xrayGroup = new System.Windows.Forms.GroupBox();
|
||||
this._btnTurnOn = new System.Windows.Forms.Button();
|
||||
this._btnTurnOff = new System.Windows.Forms.Button();
|
||||
this._paramGroup = new System.Windows.Forms.GroupBox();
|
||||
this._lblVoltage = new System.Windows.Forms.Label();
|
||||
this._nudVoltage = new System.Windows.Forms.NumericUpDown();
|
||||
this._btnSetVoltage = new System.Windows.Forms.Button();
|
||||
this._lblCurrent = new System.Windows.Forms.Label();
|
||||
this._nudCurrent = new System.Windows.Forms.NumericUpDown();
|
||||
this._btnSetCurrent = new System.Windows.Forms.Button();
|
||||
this._statusGroup = new System.Windows.Forms.GroupBox();
|
||||
this._btnReadVoltage = new System.Windows.Forms.Button();
|
||||
this._btnReadCurrent = new System.Windows.Forms.Button();
|
||||
this._btnReadSystemStatus = new System.Windows.Forms.Button();
|
||||
this._btnReadErrors = new System.Windows.Forms.Button();
|
||||
this._maintGroup = new System.Windows.Forms.GroupBox();
|
||||
this._btnWarmUp = new System.Windows.Forms.Button();
|
||||
this._btnTraining = new System.Windows.Forms.Button();
|
||||
this._btnFilamentCalibration = new System.Windows.Forms.Button();
|
||||
this._btnAutoCenter = new System.Windows.Forms.Button();
|
||||
this._btnTxiOn = new System.Windows.Forms.Button();
|
||||
this._btnTxiOff = new System.Windows.Forms.Button();
|
||||
this._btnForceExit = new System.Windows.Forms.Button();
|
||||
this._logGroup = new System.Windows.Forms.GroupBox();
|
||||
this._rtbLog = new System.Windows.Forms.RichTextBox();
|
||||
this._mainLayout.SuspendLayout();
|
||||
this._operationPanel.SuspendLayout();
|
||||
this._connGroup.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudPort)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudSourcePort)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudStationNumber)).BeginInit();
|
||||
this._xrayGroup.SuspendLayout();
|
||||
this._paramGroup.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudVoltage)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudCurrent)).BeginInit();
|
||||
this._statusGroup.SuspendLayout();
|
||||
this._maintGroup.SuspendLayout();
|
||||
this._logGroup.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// _mainLayout
|
||||
//
|
||||
this._mainLayout.ColumnCount = 1;
|
||||
this._mainLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this._mainLayout.Controls.Add(this._operationPanel, 0, 0);
|
||||
this._mainLayout.Controls.Add(this._logGroup, 0, 1);
|
||||
this._mainLayout.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._mainLayout.Location = new System.Drawing.Point(0, 0);
|
||||
this._mainLayout.Name = "_mainLayout";
|
||||
this._mainLayout.Padding = new System.Windows.Forms.Padding(8);
|
||||
this._mainLayout.RowCount = 2;
|
||||
this._mainLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 450F));
|
||||
this._mainLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this._mainLayout.Size = new System.Drawing.Size(780, 700);
|
||||
this._mainLayout.TabIndex = 0;
|
||||
//
|
||||
// _operationPanel
|
||||
//
|
||||
this._operationPanel.Controls.Add(this._connGroup);
|
||||
this._operationPanel.Controls.Add(this._xrayGroup);
|
||||
this._operationPanel.Controls.Add(this._paramGroup);
|
||||
this._operationPanel.Controls.Add(this._statusGroup);
|
||||
this._operationPanel.Controls.Add(this._maintGroup);
|
||||
this._operationPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._operationPanel.Location = new System.Drawing.Point(11, 11);
|
||||
this._operationPanel.Name = "_operationPanel";
|
||||
this._operationPanel.Size = new System.Drawing.Size(758, 444);
|
||||
this._operationPanel.TabIndex = 0;
|
||||
//
|
||||
// _connGroup
|
||||
//
|
||||
this._connGroup.Controls.Add(this._lblIpAddress);
|
||||
this._connGroup.Controls.Add(this._txtIpAddress);
|
||||
this._connGroup.Controls.Add(this._lblPort);
|
||||
this._connGroup.Controls.Add(this._nudPort);
|
||||
this._connGroup.Controls.Add(this._lblCpuName);
|
||||
this._connGroup.Controls.Add(this._txtCpuName);
|
||||
this._connGroup.Controls.Add(this._lblSourcePort);
|
||||
this._connGroup.Controls.Add(this._nudSourcePort);
|
||||
this._connGroup.Controls.Add(this._lblStationNumber);
|
||||
this._connGroup.Controls.Add(this._nudStationNumber);
|
||||
this._connGroup.Controls.Add(this._btnInitialize);
|
||||
this._connGroup.Controls.Add(this._btnConnectVariables);
|
||||
this._connGroup.Controls.Add(this._btnDisconnect);
|
||||
this._connGroup.Controls.Add(this._lblConnectionState);
|
||||
this._connGroup.Controls.Add(this._lblPviState);
|
||||
this._connGroup.Controls.Add(this._lblHeartbeat);
|
||||
this._connGroup.Location = new System.Drawing.Point(0, 0);
|
||||
this._connGroup.Name = "_connGroup";
|
||||
this._connGroup.Size = new System.Drawing.Size(750, 100);
|
||||
this._connGroup.TabIndex = 0;
|
||||
this._connGroup.TabStop = false;
|
||||
this._connGroup.Text = "连接参数";
|
||||
//
|
||||
// _lblIpAddress
|
||||
//
|
||||
this._lblIpAddress.AutoSize = true;
|
||||
this._lblIpAddress.Location = new System.Drawing.Point(10, 25);
|
||||
this._lblIpAddress.Name = "_lblIpAddress";
|
||||
this._lblIpAddress.Size = new System.Drawing.Size(85, 21);
|
||||
this._lblIpAddress.TabIndex = 0;
|
||||
this._lblIpAddress.Text = "IP地址:";
|
||||
//
|
||||
// _txtIpAddress
|
||||
//
|
||||
this._txtIpAddress.Location = new System.Drawing.Point(70, 22);
|
||||
this._txtIpAddress.Name = "_txtIpAddress";
|
||||
this._txtIpAddress.Size = new System.Drawing.Size(120, 31);
|
||||
this._txtIpAddress.TabIndex = 1;
|
||||
this._txtIpAddress.Text = "192.168.12.10";
|
||||
//
|
||||
// _lblPort
|
||||
//
|
||||
this._lblPort.AutoSize = true;
|
||||
this._lblPort.Location = new System.Drawing.Point(200, 25);
|
||||
this._lblPort.Name = "_lblPort";
|
||||
this._lblPort.Size = new System.Drawing.Size(63, 21);
|
||||
this._lblPort.TabIndex = 2;
|
||||
this._lblPort.Text = "端口:";
|
||||
//
|
||||
// _nudPort
|
||||
//
|
||||
this._nudPort.Location = new System.Drawing.Point(240, 22);
|
||||
this._nudPort.Maximum = new decimal(new int[] {
|
||||
65535,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudPort.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudPort.Name = "_nudPort";
|
||||
this._nudPort.Size = new System.Drawing.Size(70, 31);
|
||||
this._nudPort.TabIndex = 3;
|
||||
this._nudPort.Value = new decimal(new int[] {
|
||||
11159,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// _lblCpuName
|
||||
//
|
||||
this._lblCpuName.AutoSize = true;
|
||||
this._lblCpuName.Location = new System.Drawing.Point(320, 25);
|
||||
this._lblCpuName.Name = "_lblCpuName";
|
||||
this._lblCpuName.Size = new System.Drawing.Size(96, 21);
|
||||
this._lblCpuName.TabIndex = 4;
|
||||
this._lblCpuName.Text = "CPU名称:";
|
||||
//
|
||||
// _txtCpuName
|
||||
//
|
||||
this._txtCpuName.Location = new System.Drawing.Point(390, 22);
|
||||
this._txtCpuName.Name = "_txtCpuName";
|
||||
this._txtCpuName.Size = new System.Drawing.Size(80, 31);
|
||||
this._txtCpuName.TabIndex = 5;
|
||||
this._txtCpuName.Text = "cpu";
|
||||
//
|
||||
// _lblSourcePort
|
||||
//
|
||||
this._lblSourcePort.AutoSize = true;
|
||||
this._lblSourcePort.Location = new System.Drawing.Point(480, 25);
|
||||
this._lblSourcePort.Name = "_lblSourcePort";
|
||||
this._lblSourcePort.Size = new System.Drawing.Size(84, 21);
|
||||
this._lblSourcePort.TabIndex = 6;
|
||||
this._lblSourcePort.Text = "源端口:";
|
||||
//
|
||||
// _nudSourcePort
|
||||
//
|
||||
this._nudSourcePort.Location = new System.Drawing.Point(540, 22);
|
||||
this._nudSourcePort.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudSourcePort.Name = "_nudSourcePort";
|
||||
this._nudSourcePort.Size = new System.Drawing.Size(70, 31);
|
||||
this._nudSourcePort.TabIndex = 7;
|
||||
this._nudSourcePort.Value = new decimal(new int[] {
|
||||
11,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// _lblStationNumber
|
||||
//
|
||||
this._lblStationNumber.AutoSize = true;
|
||||
this._lblStationNumber.Location = new System.Drawing.Point(620, 25);
|
||||
this._lblStationNumber.Name = "_lblStationNumber";
|
||||
this._lblStationNumber.Size = new System.Drawing.Size(63, 21);
|
||||
this._lblStationNumber.TabIndex = 8;
|
||||
this._lblStationNumber.Text = "站号:";
|
||||
//
|
||||
// _nudStationNumber
|
||||
//
|
||||
this._nudStationNumber.Location = new System.Drawing.Point(660, 22);
|
||||
this._nudStationNumber.Maximum = new decimal(new int[] {
|
||||
255,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudStationNumber.Name = "_nudStationNumber";
|
||||
this._nudStationNumber.Size = new System.Drawing.Size(60, 31);
|
||||
this._nudStationNumber.TabIndex = 9;
|
||||
this._nudStationNumber.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// _btnInitialize
|
||||
//
|
||||
this._btnInitialize.Location = new System.Drawing.Point(10, 58);
|
||||
this._btnInitialize.Name = "_btnInitialize";
|
||||
this._btnInitialize.Size = new System.Drawing.Size(120, 28);
|
||||
this._btnInitialize.TabIndex = 10;
|
||||
this._btnInitialize.Text = "初始化连接";
|
||||
this._btnInitialize.Click += new System.EventHandler(this.OnInitialize);
|
||||
//
|
||||
// _btnConnectVariables
|
||||
//
|
||||
this._btnConnectVariables.Enabled = false;
|
||||
this._btnConnectVariables.Location = new System.Drawing.Point(140, 58);
|
||||
this._btnConnectVariables.Name = "_btnConnectVariables";
|
||||
this._btnConnectVariables.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnConnectVariables.TabIndex = 11;
|
||||
this._btnConnectVariables.Text = "连接变量";
|
||||
this._btnConnectVariables.Click += new System.EventHandler(this.OnConnectVariables);
|
||||
//
|
||||
// _btnDisconnect
|
||||
//
|
||||
this._btnDisconnect.Enabled = false;
|
||||
this._btnDisconnect.Location = new System.Drawing.Point(250, 58);
|
||||
this._btnDisconnect.Name = "_btnDisconnect";
|
||||
this._btnDisconnect.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnDisconnect.TabIndex = 12;
|
||||
this._btnDisconnect.Text = "断开连接";
|
||||
this._btnDisconnect.Click += new System.EventHandler(this.OnDisconnect);
|
||||
//
|
||||
// _lblConnectionState
|
||||
//
|
||||
this._lblConnectionState.ForeColor = System.Drawing.Color.Red;
|
||||
this._lblConnectionState.Location = new System.Drawing.Point(370, 63);
|
||||
this._lblConnectionState.Name = "_lblConnectionState";
|
||||
this._lblConnectionState.Size = new System.Drawing.Size(174, 23);
|
||||
this._lblConnectionState.TabIndex = 13;
|
||||
this._lblConnectionState.Text = "状态: 未连接";
|
||||
//
|
||||
// _lblPviState
|
||||
//
|
||||
this._lblPviState.AutoSize = true;
|
||||
this._lblPviState.ForeColor = System.Drawing.Color.Gray;
|
||||
this._lblPviState.Location = new System.Drawing.Point(575, 63);
|
||||
this._lblPviState.Name = "_lblPviState";
|
||||
this._lblPviState.Size = new System.Drawing.Size(73, 21);
|
||||
this._lblPviState.TabIndex = 13;
|
||||
this._lblPviState.Text = "未连接";
|
||||
//
|
||||
// _lblHeartbeat
|
||||
//
|
||||
this._lblHeartbeat.Font = new System.Drawing.Font("Segoe UI", 12F);
|
||||
this._lblHeartbeat.ForeColor = System.Drawing.Color.Gray;
|
||||
this._lblHeartbeat.Location = new System.Drawing.Point(720, 58);
|
||||
this._lblHeartbeat.Name = "_lblHeartbeat";
|
||||
this._lblHeartbeat.Size = new System.Drawing.Size(24, 24);
|
||||
this._lblHeartbeat.TabIndex = 15;
|
||||
this._lblHeartbeat.Text = "●";
|
||||
//
|
||||
// _xrayGroup
|
||||
//
|
||||
this._xrayGroup.Controls.Add(this._btnTurnOn);
|
||||
this._xrayGroup.Controls.Add(this._btnTurnOff);
|
||||
this._xrayGroup.Location = new System.Drawing.Point(0, 105);
|
||||
this._xrayGroup.Name = "_xrayGroup";
|
||||
this._xrayGroup.Size = new System.Drawing.Size(750, 65);
|
||||
this._xrayGroup.TabIndex = 1;
|
||||
this._xrayGroup.TabStop = false;
|
||||
this._xrayGroup.Text = "射线控制";
|
||||
//
|
||||
// _btnTurnOn
|
||||
//
|
||||
this._btnTurnOn.Enabled = false;
|
||||
this._btnTurnOn.Location = new System.Drawing.Point(10, 25);
|
||||
this._btnTurnOn.Name = "_btnTurnOn";
|
||||
this._btnTurnOn.Size = new System.Drawing.Size(150, 28);
|
||||
this._btnTurnOn.TabIndex = 0;
|
||||
this._btnTurnOn.Text = "开启高压 (TurnOn)";
|
||||
this._btnTurnOn.Click += new System.EventHandler(this.OnTurnOn);
|
||||
//
|
||||
// _btnTurnOff
|
||||
//
|
||||
this._btnTurnOff.Enabled = false;
|
||||
this._btnTurnOff.Location = new System.Drawing.Point(170, 25);
|
||||
this._btnTurnOff.Name = "_btnTurnOff";
|
||||
this._btnTurnOff.Size = new System.Drawing.Size(150, 28);
|
||||
this._btnTurnOff.TabIndex = 1;
|
||||
this._btnTurnOff.Text = "关闭高压 (TurnOff)";
|
||||
this._btnTurnOff.Click += new System.EventHandler(this.OnTurnOff);
|
||||
//
|
||||
// _paramGroup
|
||||
//
|
||||
this._paramGroup.Controls.Add(this._lblVoltage);
|
||||
this._paramGroup.Controls.Add(this._nudVoltage);
|
||||
this._paramGroup.Controls.Add(this._btnSetVoltage);
|
||||
this._paramGroup.Controls.Add(this._lblCurrent);
|
||||
this._paramGroup.Controls.Add(this._nudCurrent);
|
||||
this._paramGroup.Controls.Add(this._btnSetCurrent);
|
||||
this._paramGroup.Location = new System.Drawing.Point(0, 175);
|
||||
this._paramGroup.Name = "_paramGroup";
|
||||
this._paramGroup.Size = new System.Drawing.Size(750, 65);
|
||||
this._paramGroup.TabIndex = 2;
|
||||
this._paramGroup.TabStop = false;
|
||||
this._paramGroup.Text = "参数设置";
|
||||
//
|
||||
// _lblVoltage
|
||||
//
|
||||
this._lblVoltage.AutoSize = true;
|
||||
this._lblVoltage.Location = new System.Drawing.Point(10, 28);
|
||||
this._lblVoltage.Name = "_lblVoltage";
|
||||
this._lblVoltage.Size = new System.Drawing.Size(107, 21);
|
||||
this._lblVoltage.TabIndex = 0;
|
||||
this._lblVoltage.Text = "电压(kV):";
|
||||
//
|
||||
// _nudVoltage
|
||||
//
|
||||
this._nudVoltage.DecimalPlaces = 1;
|
||||
this._nudVoltage.Location = new System.Drawing.Point(80, 25);
|
||||
this._nudVoltage.Maximum = new decimal(new int[] {
|
||||
300,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudVoltage.Name = "_nudVoltage";
|
||||
this._nudVoltage.Size = new System.Drawing.Size(80, 31);
|
||||
this._nudVoltage.TabIndex = 1;
|
||||
//
|
||||
// _btnSetVoltage
|
||||
//
|
||||
this._btnSetVoltage.Enabled = false;
|
||||
this._btnSetVoltage.Location = new System.Drawing.Point(170, 23);
|
||||
this._btnSetVoltage.Name = "_btnSetVoltage";
|
||||
this._btnSetVoltage.Size = new System.Drawing.Size(90, 28);
|
||||
this._btnSetVoltage.TabIndex = 2;
|
||||
this._btnSetVoltage.Text = "设置电压";
|
||||
this._btnSetVoltage.Click += new System.EventHandler(this.OnSetVoltage);
|
||||
//
|
||||
// _lblCurrent
|
||||
//
|
||||
this._lblCurrent.AutoSize = true;
|
||||
this._lblCurrent.Location = new System.Drawing.Point(280, 28);
|
||||
this._lblCurrent.Name = "_lblCurrent";
|
||||
this._lblCurrent.Size = new System.Drawing.Size(117, 21);
|
||||
this._lblCurrent.TabIndex = 3;
|
||||
this._lblCurrent.Text = "电流(μA):";
|
||||
//
|
||||
// _nudCurrent
|
||||
//
|
||||
this._nudCurrent.DecimalPlaces = 1;
|
||||
this._nudCurrent.Location = new System.Drawing.Point(350, 25);
|
||||
this._nudCurrent.Maximum = new decimal(new int[] {
|
||||
5000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this._nudCurrent.Name = "_nudCurrent";
|
||||
this._nudCurrent.Size = new System.Drawing.Size(80, 31);
|
||||
this._nudCurrent.TabIndex = 4;
|
||||
//
|
||||
// _btnSetCurrent
|
||||
//
|
||||
this._btnSetCurrent.Enabled = false;
|
||||
this._btnSetCurrent.Location = new System.Drawing.Point(440, 23);
|
||||
this._btnSetCurrent.Name = "_btnSetCurrent";
|
||||
this._btnSetCurrent.Size = new System.Drawing.Size(90, 28);
|
||||
this._btnSetCurrent.TabIndex = 5;
|
||||
this._btnSetCurrent.Text = "设置电流";
|
||||
this._btnSetCurrent.Click += new System.EventHandler(this.OnSetCurrent);
|
||||
//
|
||||
// _statusGroup
|
||||
//
|
||||
this._statusGroup.Controls.Add(this._btnReadVoltage);
|
||||
this._statusGroup.Controls.Add(this._btnReadCurrent);
|
||||
this._statusGroup.Controls.Add(this._btnReadSystemStatus);
|
||||
this._statusGroup.Controls.Add(this._btnReadErrors);
|
||||
this._statusGroup.Location = new System.Drawing.Point(0, 245);
|
||||
this._statusGroup.Name = "_statusGroup";
|
||||
this._statusGroup.Size = new System.Drawing.Size(750, 64);
|
||||
this._statusGroup.TabIndex = 3;
|
||||
this._statusGroup.TabStop = false;
|
||||
this._statusGroup.Text = "状态读取";
|
||||
//
|
||||
// _btnReadVoltage
|
||||
//
|
||||
this._btnReadVoltage.Enabled = false;
|
||||
this._btnReadVoltage.Location = new System.Drawing.Point(10, 25);
|
||||
this._btnReadVoltage.Name = "_btnReadVoltage";
|
||||
this._btnReadVoltage.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnReadVoltage.TabIndex = 0;
|
||||
this._btnReadVoltage.Text = "读取电压";
|
||||
this._btnReadVoltage.Click += new System.EventHandler(this.OnReadVoltage);
|
||||
//
|
||||
// _btnReadCurrent
|
||||
//
|
||||
this._btnReadCurrent.Enabled = false;
|
||||
this._btnReadCurrent.Location = new System.Drawing.Point(120, 25);
|
||||
this._btnReadCurrent.Name = "_btnReadCurrent";
|
||||
this._btnReadCurrent.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnReadCurrent.TabIndex = 1;
|
||||
this._btnReadCurrent.Text = "读取电流";
|
||||
this._btnReadCurrent.Click += new System.EventHandler(this.OnReadCurrent);
|
||||
//
|
||||
// _btnReadSystemStatus
|
||||
//
|
||||
this._btnReadSystemStatus.Enabled = false;
|
||||
this._btnReadSystemStatus.Location = new System.Drawing.Point(230, 25);
|
||||
this._btnReadSystemStatus.Name = "_btnReadSystemStatus";
|
||||
this._btnReadSystemStatus.Size = new System.Drawing.Size(120, 28);
|
||||
this._btnReadSystemStatus.TabIndex = 2;
|
||||
this._btnReadSystemStatus.Text = "读取系统状态";
|
||||
this._btnReadSystemStatus.Click += new System.EventHandler(this.OnReadSystemStatus);
|
||||
//
|
||||
// _btnReadErrors
|
||||
//
|
||||
this._btnReadErrors.Enabled = false;
|
||||
this._btnReadErrors.Location = new System.Drawing.Point(360, 25);
|
||||
this._btnReadErrors.Name = "_btnReadErrors";
|
||||
this._btnReadErrors.Size = new System.Drawing.Size(120, 28);
|
||||
this._btnReadErrors.TabIndex = 3;
|
||||
this._btnReadErrors.Text = "读取错误信息";
|
||||
this._btnReadErrors.Click += new System.EventHandler(this.OnReadErrors);
|
||||
//
|
||||
// _maintGroup
|
||||
//
|
||||
this._maintGroup.Controls.Add(this._btnWarmUp);
|
||||
this._maintGroup.Controls.Add(this._btnTraining);
|
||||
this._maintGroup.Controls.Add(this._btnFilamentCalibration);
|
||||
this._maintGroup.Controls.Add(this._btnAutoCenter);
|
||||
this._maintGroup.Controls.Add(this._btnTxiOn);
|
||||
this._maintGroup.Controls.Add(this._btnTxiOff);
|
||||
this._maintGroup.Controls.Add(this._btnForceExit);
|
||||
this._maintGroup.Location = new System.Drawing.Point(0, 317);
|
||||
this._maintGroup.Name = "_maintGroup";
|
||||
this._maintGroup.Size = new System.Drawing.Size(750, 76);
|
||||
this._maintGroup.TabIndex = 4;
|
||||
this._maintGroup.TabStop = false;
|
||||
this._maintGroup.Text = "维护操作";
|
||||
//
|
||||
// _btnWarmUp
|
||||
//
|
||||
this._btnWarmUp.Enabled = false;
|
||||
this._btnWarmUp.Location = new System.Drawing.Point(10, 25);
|
||||
this._btnWarmUp.Name = "_btnWarmUp";
|
||||
this._btnWarmUp.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnWarmUp.TabIndex = 0;
|
||||
this._btnWarmUp.Text = "暖机设置";
|
||||
this._btnWarmUp.Click += new System.EventHandler(this.OnWarmUp);
|
||||
//
|
||||
// _btnTraining
|
||||
//
|
||||
this._btnTraining.Enabled = false;
|
||||
this._btnTraining.Location = new System.Drawing.Point(120, 25);
|
||||
this._btnTraining.Name = "_btnTraining";
|
||||
this._btnTraining.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnTraining.TabIndex = 1;
|
||||
this._btnTraining.Text = "训机设置";
|
||||
this._btnTraining.Click += new System.EventHandler(this.OnTraining);
|
||||
//
|
||||
// _btnFilamentCalibration
|
||||
//
|
||||
this._btnFilamentCalibration.Enabled = false;
|
||||
this._btnFilamentCalibration.Location = new System.Drawing.Point(230, 25);
|
||||
this._btnFilamentCalibration.Name = "_btnFilamentCalibration";
|
||||
this._btnFilamentCalibration.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnFilamentCalibration.TabIndex = 2;
|
||||
this._btnFilamentCalibration.Text = "灯丝校准";
|
||||
this._btnFilamentCalibration.Click += new System.EventHandler(this.OnFilamentCalibration);
|
||||
//
|
||||
// _btnAutoCenter
|
||||
//
|
||||
this._btnAutoCenter.Enabled = false;
|
||||
this._btnAutoCenter.Location = new System.Drawing.Point(340, 25);
|
||||
this._btnAutoCenter.Name = "_btnAutoCenter";
|
||||
this._btnAutoCenter.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnAutoCenter.TabIndex = 3;
|
||||
this._btnAutoCenter.Text = "自动定心";
|
||||
this._btnAutoCenter.Click += new System.EventHandler(this.OnAutoCenter);
|
||||
//
|
||||
// _btnTxiOn
|
||||
//
|
||||
this._btnTxiOn.Enabled = false;
|
||||
this._btnTxiOn.Location = new System.Drawing.Point(450, 25);
|
||||
this._btnTxiOn.Name = "_btnTxiOn";
|
||||
this._btnTxiOn.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnTxiOn.TabIndex = 4;
|
||||
this._btnTxiOn.Text = "TXI ON";
|
||||
this._btnTxiOn.Click += new System.EventHandler(this.OnTxiOn);
|
||||
//
|
||||
// _btnTxiOff
|
||||
//
|
||||
this._btnTxiOff.Enabled = false;
|
||||
this._btnTxiOff.Location = new System.Drawing.Point(560, 25);
|
||||
this._btnTxiOff.Name = "_btnTxiOff";
|
||||
this._btnTxiOff.Size = new System.Drawing.Size(100, 28);
|
||||
this._btnTxiOff.TabIndex = 5;
|
||||
this._btnTxiOff.Text = "TXI OFF";
|
||||
this._btnTxiOff.Click += new System.EventHandler(this.OnTxiOff);
|
||||
//
|
||||
// _btnForceExit
|
||||
//
|
||||
this._btnForceExit.BackColor = System.Drawing.Color.DarkRed;
|
||||
this._btnForceExit.ForeColor = System.Drawing.Color.White;
|
||||
this._btnForceExit.Location = new System.Drawing.Point(670, 25);
|
||||
this._btnForceExit.Name = "_btnForceExit";
|
||||
this._btnForceExit.Size = new System.Drawing.Size(75, 28);
|
||||
this._btnForceExit.TabIndex = 6;
|
||||
this._btnForceExit.Text = "强制退出";
|
||||
this._btnForceExit.UseVisualStyleBackColor = false;
|
||||
this._btnForceExit.Click += new System.EventHandler(this.OnForceExitClick);
|
||||
//
|
||||
// _logGroup
|
||||
//
|
||||
this._logGroup.Controls.Add(this._rtbLog);
|
||||
this._logGroup.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._logGroup.Location = new System.Drawing.Point(11, 461);
|
||||
this._logGroup.Name = "_logGroup";
|
||||
this._logGroup.Size = new System.Drawing.Size(758, 228);
|
||||
this._logGroup.TabIndex = 1;
|
||||
this._logGroup.TabStop = false;
|
||||
this._logGroup.Text = "日志输出";
|
||||
//
|
||||
// _rtbLog
|
||||
//
|
||||
this._rtbLog.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(30)))), ((int)(((byte)(30)))));
|
||||
this._rtbLog.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._rtbLog.Font = new System.Drawing.Font("Consolas", 9F);
|
||||
this._rtbLog.ForeColor = System.Drawing.Color.LightGreen;
|
||||
this._rtbLog.Location = new System.Drawing.Point(3, 27);
|
||||
this._rtbLog.Name = "_rtbLog";
|
||||
this._rtbLog.ReadOnly = true;
|
||||
this._rtbLog.Size = new System.Drawing.Size(752, 198);
|
||||
this._rtbLog.TabIndex = 0;
|
||||
this._rtbLog.Text = "";
|
||||
//
|
||||
// XplorePlaneCometHost
|
||||
//
|
||||
this.ClientSize = new System.Drawing.Size(780, 700);
|
||||
this.Controls.Add(this._mainLayout);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(780, 600);
|
||||
this.Name = "XplorePlaneCometHost";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "XplorePlane Comet Host";
|
||||
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing);
|
||||
this._mainLayout.ResumeLayout(false);
|
||||
this._operationPanel.ResumeLayout(false);
|
||||
this._connGroup.ResumeLayout(false);
|
||||
this._connGroup.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudPort)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudSourcePort)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudStationNumber)).EndInit();
|
||||
this._xrayGroup.ResumeLayout(false);
|
||||
this._paramGroup.ResumeLayout(false);
|
||||
this._paramGroup.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudVoltage)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this._nudCurrent)).EndInit();
|
||||
this._statusGroup.ResumeLayout(false);
|
||||
this._maintGroup.ResumeLayout(false);
|
||||
this._logGroup.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// 布局控件
|
||||
private System.Windows.Forms.TableLayoutPanel _mainLayout;
|
||||
private System.Windows.Forms.Panel _operationPanel;
|
||||
private System.Windows.Forms.GroupBox _connGroup;
|
||||
private System.Windows.Forms.GroupBox _xrayGroup;
|
||||
private System.Windows.Forms.GroupBox _paramGroup;
|
||||
private System.Windows.Forms.GroupBox _statusGroup;
|
||||
private System.Windows.Forms.GroupBox _logGroup;
|
||||
|
||||
// 连接参数标签
|
||||
private System.Windows.Forms.Label _lblIpAddress;
|
||||
private System.Windows.Forms.Label _lblPort;
|
||||
private System.Windows.Forms.Label _lblCpuName;
|
||||
private System.Windows.Forms.Label _lblSourcePort;
|
||||
private System.Windows.Forms.Label _lblStationNumber;
|
||||
|
||||
// 连接参数输入
|
||||
private System.Windows.Forms.TextBox _txtIpAddress;
|
||||
private System.Windows.Forms.NumericUpDown _nudPort;
|
||||
private System.Windows.Forms.TextBox _txtCpuName;
|
||||
private System.Windows.Forms.NumericUpDown _nudSourcePort;
|
||||
private System.Windows.Forms.NumericUpDown _nudStationNumber;
|
||||
|
||||
// 连接操作按钮
|
||||
private System.Windows.Forms.Button _btnInitialize;
|
||||
private System.Windows.Forms.Button _btnConnectVariables;
|
||||
private System.Windows.Forms.Button _btnDisconnect;
|
||||
private System.Windows.Forms.Label _lblConnectionState;
|
||||
private System.Windows.Forms.Label _lblPviState;
|
||||
private System.Windows.Forms.Label _lblHeartbeat;
|
||||
|
||||
// 射线控制按钮
|
||||
private System.Windows.Forms.Button _btnTurnOn;
|
||||
private System.Windows.Forms.Button _btnTurnOff;
|
||||
|
||||
// 参数设置
|
||||
private System.Windows.Forms.Label _lblVoltage;
|
||||
private System.Windows.Forms.NumericUpDown _nudVoltage;
|
||||
private System.Windows.Forms.Button _btnSetVoltage;
|
||||
private System.Windows.Forms.Label _lblCurrent;
|
||||
private System.Windows.Forms.NumericUpDown _nudCurrent;
|
||||
private System.Windows.Forms.Button _btnSetCurrent;
|
||||
|
||||
// 状态读取按钮
|
||||
private System.Windows.Forms.Button _btnReadVoltage;
|
||||
private System.Windows.Forms.Button _btnReadCurrent;
|
||||
private System.Windows.Forms.Button _btnReadSystemStatus;
|
||||
private System.Windows.Forms.Button _btnReadErrors;
|
||||
|
||||
// 维护操作
|
||||
private System.Windows.Forms.GroupBox _maintGroup;
|
||||
private System.Windows.Forms.Button _btnWarmUp;
|
||||
private System.Windows.Forms.Button _btnTraining;
|
||||
private System.Windows.Forms.Button _btnFilamentCalibration;
|
||||
private System.Windows.Forms.Button _btnAutoCenter;
|
||||
private System.Windows.Forms.Button _btnTxiOn;
|
||||
private System.Windows.Forms.Button _btnTxiOff;
|
||||
private System.Windows.Forms.Button _btnForceExit;
|
||||
|
||||
// 日志输出
|
||||
private System.Windows.Forms.RichTextBox _rtbLog;
|
||||
|
||||
// 托盘图标
|
||||
private System.Windows.Forms.NotifyIcon _notifyIcon;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,995 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using XP.Hardware.RaySource.Comet;
|
||||
using XP.Hardware.RaySource.Comet.Host.Pipe;
|
||||
using XP.Hardware.RaySource.Comet.Host.Properties;
|
||||
using XP.Hardware.RaySource.Comet.Messages;
|
||||
using XP.Hardware.RaySource.Comet.Messages.Responses;
|
||||
|
||||
namespace XP.Hardware.RaySource.Comet.Host
|
||||
{
|
||||
/// <summary>
|
||||
/// XplorePlane Comet Host 主窗体
|
||||
/// 集成托盘图标、管道通信、PVI 客户端生命周期和功能测试按钮
|
||||
/// </summary>
|
||||
public partial class XplorePlaneCometHost : Form
|
||||
{
|
||||
#region 管道通信常量和字段
|
||||
|
||||
/// <summary>
|
||||
/// 命令管道名称(客户端写 → Host 读)
|
||||
/// </summary>
|
||||
private const string CmdPipeName = "XP.Hardware.RaySource.Comet.Cmd";
|
||||
|
||||
/// <summary>
|
||||
/// 响应管道名称(Host 写 → 客户端读)
|
||||
/// </summary>
|
||||
private const string RspPipeName = "XP.Hardware.RaySource.Comet.Rsp";
|
||||
|
||||
/// <summary>
|
||||
/// 写入锁,防止命令响应和推送消息交错
|
||||
/// </summary>
|
||||
private static readonly object WriteLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 管道是否已连接,用于控制日志是否推送到管道
|
||||
/// </summary>
|
||||
private volatile bool _isPipeConnected;
|
||||
|
||||
/// <summary>
|
||||
/// 管道轮询定时器
|
||||
/// </summary>
|
||||
private System.Windows.Forms.Timer _pipeTimer;
|
||||
|
||||
/// <summary>
|
||||
/// 命令管道服务端
|
||||
/// </summary>
|
||||
private NamedPipeServerStream _cmdPipe;
|
||||
|
||||
/// <summary>
|
||||
/// 响应管道服务端
|
||||
/// </summary>
|
||||
private NamedPipeServerStream _rspPipe;
|
||||
|
||||
/// <summary>
|
||||
/// 管道读取器
|
||||
/// </summary>
|
||||
private StreamReader _pipeReader;
|
||||
|
||||
/// <summary>
|
||||
/// 管道写入器
|
||||
/// </summary>
|
||||
private StreamWriter _pipeWriter;
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在等待客户端连接
|
||||
/// </summary>
|
||||
private bool _isWaitingConnection;
|
||||
|
||||
/// <summary>
|
||||
/// 异步连接结果(命令管道)
|
||||
/// </summary>
|
||||
private IAsyncResult _cmdConnectResult;
|
||||
|
||||
/// <summary>
|
||||
/// 异步连接结果(响应管道)
|
||||
/// </summary>
|
||||
private IAsyncResult _rspConnectResult;
|
||||
|
||||
/// <summary>
|
||||
/// Win32 PeekNamedPipe API,用于非阻塞检测管道中是否有可读数据
|
||||
/// StreamReader.Peek() 在异步模式 NamedPipe 上不可靠:
|
||||
/// 当内部缓冲区为空时,Peek 调用底层同步 Read,异步管道会返回 0 字节,
|
||||
/// 导致 StreamReader 误判为 EOF,后续所有读取永远返回 -1/null
|
||||
/// </summary>
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool PeekNamedPipe(
|
||||
SafePipeHandle hNamedPipe,
|
||||
IntPtr lpBuffer,
|
||||
uint nBufferSize,
|
||||
IntPtr lpBytesRead,
|
||||
out uint lpTotalBytesAvail,
|
||||
IntPtr lpBytesLeftThisMessage);
|
||||
|
||||
/// <summary>
|
||||
/// 检查命令管道中是否有可读数据(非阻塞)
|
||||
/// </summary>
|
||||
private bool HasPipeData()
|
||||
{
|
||||
if (_cmdPipe == null || !_cmdPipe.IsConnected)
|
||||
return false;
|
||||
|
||||
bool result = PeekNamedPipe(
|
||||
_cmdPipe.SafePipeHandle,
|
||||
IntPtr.Zero, 0, IntPtr.Zero,
|
||||
out uint bytesAvailable,
|
||||
IntPtr.Zero);
|
||||
|
||||
return result && bytesAvailable > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Comet Timer常量
|
||||
/// <summary>
|
||||
/// 连接状态定时器
|
||||
/// </summary>
|
||||
private System.Windows.Forms.Timer _pviConnectTimer;
|
||||
|
||||
/// <summary>
|
||||
/// 看门狗定时器
|
||||
/// </summary>
|
||||
private System.Windows.Forms.Timer _watchDogTimer;
|
||||
|
||||
/// <summary>
|
||||
/// 心跳闪烁状态(true=绿色,false=灰色)
|
||||
/// </summary>
|
||||
private bool _heartbeatToggle;
|
||||
|
||||
#endregion
|
||||
|
||||
public XplorePlaneCometHost()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeTrayIcon();
|
||||
SetupLogger();
|
||||
SubscribeLocalEvents();
|
||||
StartPipeLoop();
|
||||
StartCometPviTimer();
|
||||
}
|
||||
|
||||
#region 托盘图标
|
||||
|
||||
/// <summary>
|
||||
/// 初始化系统托盘图标和右键菜单
|
||||
/// </summary>
|
||||
private void InitializeTrayIcon()
|
||||
{
|
||||
var contextMenu = new ContextMenuStrip();
|
||||
contextMenu.Items.Add("XplorePlane Comet Host", null, null).Enabled = false;
|
||||
contextMenu.Items.Add(new ToolStripSeparator());
|
||||
contextMenu.Items.Add("测试窗口|Test(&S)", null, (s, e) =>
|
||||
{
|
||||
this.ShowInTaskbar = true;
|
||||
this.Show();
|
||||
this.WindowState = FormWindowState.Normal;
|
||||
this.Activate();
|
||||
});
|
||||
contextMenu.Items.Add("退出|Exit(&X)", null, OnExitClick);
|
||||
|
||||
_notifyIcon = new NotifyIcon
|
||||
{
|
||||
Icon = Resource.Comet_Host_Icon,
|
||||
Text = "XP.Hardware.RaySource.Comet.Host",
|
||||
Visible = true,
|
||||
ContextMenuStrip = contextMenu
|
||||
};
|
||||
_notifyIcon.DoubleClick += (s, e) =>
|
||||
{
|
||||
this.ShowInTaskbar = true;
|
||||
this.Show();
|
||||
this.WindowState = FormWindowState.Normal;
|
||||
this.Activate();
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 统一日志
|
||||
|
||||
/// <summary>
|
||||
/// 设置统一日志回调
|
||||
/// 界面日志始终输出,管道推送仅在管道连接后生效
|
||||
/// </summary>
|
||||
private void SetupLogger()
|
||||
{
|
||||
CometPviClient.SetLogger((level, message, logArgs) =>
|
||||
{
|
||||
// 始终输出到界面
|
||||
string formatted = logArgs != null && logArgs.Length > 0
|
||||
? FormatLogMessage(message, logArgs)
|
||||
: message;
|
||||
AppendLog($"[{level}] {formatted}");
|
||||
|
||||
// 管道已连接时,同步推送到主进程
|
||||
if (_isPipeConnected)
|
||||
{
|
||||
var logResponse = new LogResponse
|
||||
{
|
||||
Success = true,
|
||||
PushType = "Log",
|
||||
Level = level.ToString(),
|
||||
Message = message,
|
||||
Args = logArgs != null ? Array.ConvertAll(logArgs, a => a?.ToString() ?? "") : null
|
||||
};
|
||||
PushNotifier.SendPush(logResponse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 管道通信
|
||||
|
||||
/// <summary>
|
||||
/// 启动管道通信:创建管道并开始异步等待连接,启动轮询定时器
|
||||
/// </summary>
|
||||
private void StartPipeLoop()
|
||||
{
|
||||
// 创建管道
|
||||
_cmdPipe = new NamedPipeServerStream(CmdPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||
_rspPipe = new NamedPipeServerStream(RspPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||
|
||||
// 异步等待客户端连接
|
||||
_cmdConnectResult = _cmdPipe.BeginWaitForConnection(null, null);
|
||||
_rspConnectResult = _rspPipe.BeginWaitForConnection(null, null);
|
||||
_isWaitingConnection = true;
|
||||
|
||||
AppendLog("[管道] 等待客户端连接...");
|
||||
|
||||
// 启动定时器轮询(50ms 间隔)
|
||||
_pipeTimer = new System.Windows.Forms.Timer();
|
||||
_pipeTimer.Interval = 50;
|
||||
_pipeTimer.Tick += PipeTimer_Tick;
|
||||
_pipeTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在处理管道命令,防止 DoEvents 期间 Timer 重入
|
||||
/// </summary>
|
||||
private bool _isProcessingCommand;
|
||||
|
||||
/// <summary>
|
||||
/// 定时器回调:检查管道连接状态和读取命令
|
||||
/// </summary>
|
||||
private void PipeTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
// 防止 HandleInitialize 中 DoEvents 导致的 Timer 重入
|
||||
if (_isProcessingCommand)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// 阶段1:等待客户端连接
|
||||
if (_isWaitingConnection)
|
||||
{
|
||||
if (_cmdConnectResult.IsCompleted && _rspConnectResult.IsCompleted)
|
||||
{
|
||||
_cmdPipe.EndWaitForConnection(_cmdConnectResult);
|
||||
_rspPipe.EndWaitForConnection(_rspConnectResult);
|
||||
|
||||
_pipeReader = new StreamReader(_cmdPipe);
|
||||
_pipeWriter = new StreamWriter(_rspPipe) { AutoFlush = true };
|
||||
|
||||
// 初始化推送管理器
|
||||
PushNotifier.Initialize(_pipeWriter, WriteLock);
|
||||
|
||||
// 订阅 PVI 推送事件
|
||||
SubscribePviPushEvents();
|
||||
|
||||
_isPipeConnected = true;
|
||||
_isWaitingConnection = false;
|
||||
|
||||
AppendLog("[管道] 客户端已连接");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 阶段2:轮询读取命令
|
||||
if (!_cmdPipe.IsConnected)
|
||||
{
|
||||
AppendLog("[管道] 客户端已断开");
|
||||
CleanupPipe();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查管道中是否有可读数据(非阻塞)
|
||||
// 使用 Win32 PeekNamedPipe 替代 StreamReader.Peek()
|
||||
// StreamReader.Peek() 在异步模式 NamedPipe 上会误判 EOF,导致后续命令永远无法读取
|
||||
if (!HasPipeData())
|
||||
return;
|
||||
|
||||
_isProcessingCommand = true;
|
||||
try
|
||||
{
|
||||
string line = _pipeReader.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
AppendLog("[管道] 客户端已关闭连接");
|
||||
CleanupPipe();
|
||||
return;
|
||||
}
|
||||
|
||||
AppendLog($"[管道] 收到命令:{line}", Color.Cyan);
|
||||
|
||||
var command = MessageSerializer.DeserializeCommand(line);
|
||||
if (command == null)
|
||||
{
|
||||
var errorResponse = new OperationResponse
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = "命令反序列化失败"
|
||||
};
|
||||
WriteResponse(_pipeWriter, errorResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = CommandDispatcher.Dispatch(command);
|
||||
WriteResponse(_pipeWriter, response);
|
||||
|
||||
if (CommandDispatcher.ShouldExit)
|
||||
{
|
||||
AppendLog("[管道] 收到断开命令,管道循环退出");
|
||||
CleanupPipe();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isProcessingCommand = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[管道] 通信异常:{ex.Message}", Color.Red);
|
||||
CleanupPipe();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理管道资源
|
||||
/// </summary>
|
||||
private void CleanupPipe()
|
||||
{
|
||||
_pipeTimer?.Stop();
|
||||
_isPipeConnected = false;
|
||||
|
||||
try { _pipeReader?.Dispose(); } catch { }
|
||||
try { _pipeWriter?.Dispose(); } catch { }
|
||||
try { _cmdPipe?.Dispose(); } catch { }
|
||||
try { _rspPipe?.Dispose(); } catch { }
|
||||
|
||||
_pipeReader = null;
|
||||
_pipeWriter = null;
|
||||
_cmdPipe = null;
|
||||
_rspPipe = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 线程安全地写入响应到管道
|
||||
/// </summary>
|
||||
private static void WriteResponse(StreamWriter writer, RaySourceResponse response)
|
||||
{
|
||||
var json = MessageSerializer.Serialize(response);
|
||||
lock (WriteLock)
|
||||
{
|
||||
writer.WriteLine(json);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PVI 管道推送事件
|
||||
|
||||
/// <summary>
|
||||
/// 订阅 CometPviClient 事件,通过 PushNotifier 推送给主进程
|
||||
/// </summary>
|
||||
private void SubscribePviPushEvents()
|
||||
{
|
||||
CometPviClient.StatusChanged += (sender, status) =>
|
||||
{
|
||||
PushNotifier.SendPush(new StatusResponse
|
||||
{
|
||||
Success = true,
|
||||
PushType = "StatusChanged",
|
||||
SetVoltage = status.SetVoltage,
|
||||
ActualVoltage = status.ActualVoltage,
|
||||
SetCurrent = status.SetCurrent,
|
||||
ActualCurrent = status.ActualCurrent,
|
||||
IsXRayOn = status.IsXRayOn,
|
||||
WarmUpStatus = status.WarmUpStatus,
|
||||
VacuumStatus = status.VacuumStatus,
|
||||
StartUpStatus = status.StartUpStatus,
|
||||
AutoCenterStatus = status.AutoCenterStatus,
|
||||
FilamentAdjustStatus = status.FilamentAdjustStatus,
|
||||
IsInterlockActive = status.IsInterlockActive,
|
||||
WatchdogStatus = status.WatchdogStatus,
|
||||
PowerMode = status.PowerMode,
|
||||
TxiStatus = status.TxiStatus
|
||||
});
|
||||
};
|
||||
|
||||
CometPviClient.XRayStateChanged += (sender, isXRayOn) =>
|
||||
{
|
||||
PushNotifier.SendPush(new OperationResponse
|
||||
{
|
||||
Success = true,
|
||||
PushType = "XRayStateChanged",
|
||||
Data = isXRayOn
|
||||
});
|
||||
};
|
||||
|
||||
CometPviClient.ErrorOccurred += (sender, errorMessage) =>
|
||||
{
|
||||
PushNotifier.SendPush(new OperationResponse
|
||||
{
|
||||
Success = false,
|
||||
PushType = "ErrorOccurred",
|
||||
ErrorMessage = errorMessage
|
||||
});
|
||||
};
|
||||
|
||||
CometPviClient.ConnectionStateChanged += (sender, state) =>
|
||||
{
|
||||
PushNotifier.SendPush(new OperationResponse
|
||||
{
|
||||
Success = true,
|
||||
PushType = "ConnectionStateChanged",
|
||||
Data = state.ToString()
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Comet Timer事件
|
||||
|
||||
private void StartCometPviTimer()
|
||||
{
|
||||
// 启动连接状态定时器轮询(100ms 间隔)
|
||||
_pviConnectTimer = new System.Windows.Forms.Timer();
|
||||
_pviConnectTimer.Interval = 100;
|
||||
_pviConnectTimer.Tick += PviConnectTimer_Tick;
|
||||
_pviConnectTimer.Start();
|
||||
|
||||
// 启动看门狗定时器轮询(1000ms 间隔)
|
||||
_watchDogTimer = new System.Windows.Forms.Timer();
|
||||
_watchDogTimer.Interval = 1000;
|
||||
_watchDogTimer.Tick += WatchDogTimer_Tick;
|
||||
_watchDogTimer.Start();
|
||||
}
|
||||
|
||||
private void PviConnectTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool bRaySourceConnected = CometPviClient.ReadRaySourceConnectStatus();
|
||||
// 根据当前连接状态更新标签
|
||||
var state = CometPviClient.CurrentConnectionState;
|
||||
switch (state)
|
||||
{
|
||||
case PviConnectionState.RaySourceConnected:
|
||||
_lblPviState.Text = "射线源就绪";
|
||||
_lblPviState.ForeColor = Color.Green;
|
||||
break;
|
||||
case PviConnectionState.VariablesConnected:
|
||||
_lblPviState.Text = "变量已连接";
|
||||
_lblPviState.ForeColor = Color.DarkGoldenrod;
|
||||
break;
|
||||
case PviConnectionState.ServiceConnected:
|
||||
_lblPviState.Text = "Service已连接";
|
||||
_lblPviState.ForeColor = Color.Orange;
|
||||
break;
|
||||
default:
|
||||
_lblPviState.Text = "未连接";
|
||||
_lblPviState.ForeColor = Color.Red;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 连接状态定时器出错失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void WatchDogTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
CometPviClient.SetWatchDog();
|
||||
// 心跳闪烁:绿色/灰色交替
|
||||
_heartbeatToggle = !_heartbeatToggle;
|
||||
_lblHeartbeat.ForeColor = _heartbeatToggle ? Color.LimeGreen : Color.Gray;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_lblHeartbeat.ForeColor = Color.Red;
|
||||
AppendLog($"[错误] 看门狗定时器出错失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 本地界面事件订阅
|
||||
|
||||
/// <summary>
|
||||
/// 订阅 CometPviClient 事件,将状态输出到界面
|
||||
/// </summary>
|
||||
private void SubscribeLocalEvents()
|
||||
{
|
||||
// 订阅连接状态变更
|
||||
CometPviClient.ConnectionStateChanged += (sender, state) =>
|
||||
{
|
||||
AppendLog($"[连接状态] {state}");
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PviConnectionState.RaySourceConnected:
|
||||
_lblConnectionState.Text = "状态: 射线源已连接";
|
||||
_lblConnectionState.ForeColor = Color.Green;
|
||||
_btnConnectVariables.Enabled = false;
|
||||
_btnDisconnect.Enabled = true;
|
||||
_btnInitialize.Enabled = false;
|
||||
break;
|
||||
case PviConnectionState.ServiceConnected:
|
||||
_lblConnectionState.Text = "状态: PVI Service 已连接";
|
||||
_lblConnectionState.ForeColor = Color.Orange;
|
||||
_btnConnectVariables.Enabled = true;
|
||||
_btnDisconnect.Enabled = true;
|
||||
_btnInitialize.Enabled = false;
|
||||
break;
|
||||
case PviConnectionState.VariablesConnected:
|
||||
_lblConnectionState.Text = "状态: 变量已连接";
|
||||
_lblConnectionState.ForeColor = Color.DarkGoldenrod;
|
||||
SetOperationButtonsEnabled(true);
|
||||
_btnConnectVariables.Enabled = false;
|
||||
break;
|
||||
case PviConnectionState.Disconnected:
|
||||
_lblConnectionState.Text = "状态: 已断开";
|
||||
_lblConnectionState.ForeColor = Color.Red;
|
||||
SetOperationButtonsEnabled(false);
|
||||
_btnConnectVariables.Enabled = false;
|
||||
_btnDisconnect.Enabled = false;
|
||||
_btnInitialize.Enabled = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 订阅状态更新
|
||||
CometPviClient.StatusChanged += (sender, status) =>
|
||||
{
|
||||
AppendLog($"[状态更新] 电压={status.ActualVoltage}kV, 电流={status.ActualCurrent}μA, XRay={status.IsXRayOn}");
|
||||
};
|
||||
|
||||
// 订阅射线状态变更
|
||||
CometPviClient.XRayStateChanged += (sender, isOn) =>
|
||||
{
|
||||
AppendLog($"[射线状态] XRay {(isOn ? "已开启" : "已关闭")}");
|
||||
};
|
||||
|
||||
// 订阅错误事件
|
||||
CometPviClient.ErrorOccurred += (sender, errorMsg) =>
|
||||
{
|
||||
AppendLog($"[错误] {errorMsg}", Color.Red);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化日志消息,替换占位符
|
||||
/// </summary>
|
||||
private string FormatLogMessage(string message, object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = message;
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
result = result.Replace("{" + i + "}", args[i]?.ToString() ?? "null");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 按钮事件处理
|
||||
|
||||
private void OnInitialize(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_btnInitialize.Enabled = false;
|
||||
AppendLog("[操作] 开始初始化 PVI 连接...");
|
||||
CometPviClient.Initialize(
|
||||
_txtIpAddress.Text,
|
||||
(int)_nudPort.Value,
|
||||
_txtCpuName.Text,
|
||||
(int)_nudSourcePort.Value,
|
||||
(int)_nudStationNumber.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 初始化失败:{ex.Message}", Color.Red);
|
||||
_btnInitialize.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConnectVariables(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[操作] 开始连接 PVI 变量...");
|
||||
CometPviClient.ConnectVariables();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 连接变量失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisconnect(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[操作] 断开连接...");
|
||||
CometPviClient.Disconnect();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 断开连接失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTurnOn(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[操作] 开启高压...");
|
||||
CometPviClient.TurnOn();
|
||||
AppendLog("[操作] TurnOn 命令已发送");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] TurnOn 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTurnOff(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[操作] 关闭高压...");
|
||||
CometPviClient.TurnOff();
|
||||
AppendLog("[操作] TurnOff 命令已发送");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] TurnOff 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSetVoltage(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
float voltage = (float)_nudVoltage.Value;
|
||||
AppendLog($"[操作] 设置电压:{voltage} kV");
|
||||
CometPviClient.SetVoltage(voltage);
|
||||
AppendLog($"[操作] SetVoltage 命令已发送,电压={voltage}kV");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] SetVoltage 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSetCurrent(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
float current = (float)_nudCurrent.Value;
|
||||
AppendLog($"[操作] 设置电流:{current} μA");
|
||||
CometPviClient.SetCurrent(current);
|
||||
AppendLog($"[操作] SetCurrent 命令已发送,电流={current}μA");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] SetCurrent 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReadVoltage(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
float voltage = CometPviClient.ReadVoltage();
|
||||
AppendLog($"[读取] 实际电压:{voltage} kV");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] ReadVoltage 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReadCurrent(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
float current = CometPviClient.ReadCurrent();
|
||||
AppendLog($"[读取] 实际电流:{current} μA");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] ReadCurrent 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReadSystemStatus(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var status = CometPviClient.ReadSystemStatus();
|
||||
AppendLog("========== 系统状态 ==========");
|
||||
AppendLog($" 设定电压: {status.SetVoltage} kV | 实际电压: {status.ActualVoltage} kV");
|
||||
AppendLog($" 设定电流: {status.SetCurrent} μA | 实际电流: {status.ActualCurrent} μA");
|
||||
AppendLog($" 射线状态: {(status.IsXRayOn ? "开启" : "关闭")}");
|
||||
AppendLog($" 暖机: {status.WarmUpStatus} | 真空: {status.VacuumStatus}");
|
||||
AppendLog($" 训机: {status.StartUpStatus} | 自动定心: {status.AutoCenterStatus}");
|
||||
AppendLog($" 灯丝调整: {status.FilamentAdjustStatus}");
|
||||
AppendLog($" 连锁: {(status.IsInterlockActive ? "激活" : "未激活")} | 看门狗: {status.WatchdogStatus}");
|
||||
AppendLog($" 功率模式: {status.PowerMode} | TXI: {status.TxiStatus}");
|
||||
AppendLog("==============================");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] ReadSystemStatus 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReadErrors(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var errors = CometPviClient.ReadErrors();
|
||||
AppendLog("========== 错误信息 ==========");
|
||||
AppendLog($" 系统错误: {errors.SystemError}");
|
||||
AppendLog($" HSG错误: {errors.HSGError}");
|
||||
AppendLog($" 管错误: {errors.TubeError}");
|
||||
AppendLog($" 管真空错误: {errors.TubeVacError}");
|
||||
AppendLog("==============================");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] ReadErrors 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWarmUp(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行暖机设置...", Color.Yellow);
|
||||
CometPviClient.WarmUp();
|
||||
AppendLog("[维护] 暖机设置指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 暖机设置失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTraining(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行训机设置...", Color.Yellow);
|
||||
CometPviClient.Training();
|
||||
AppendLog("[维护] 训机设置指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 训机设置失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFilamentCalibration(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行灯丝校准...", Color.Yellow);
|
||||
CometPviClient.FilamentCalibration();
|
||||
AppendLog("[维护] 灯丝校准指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 灯丝校准失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAutoCenter(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行全部电压自动定心...", Color.Yellow);
|
||||
CometPviClient.AutoCenter();
|
||||
AppendLog("[维护] 自动定心指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] 自动定心失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTxiOn(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行 TXI ON...", Color.Yellow);
|
||||
CometPviClient.TxiOn();
|
||||
AppendLog("[维护] TXI ON 指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] TXI ON 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTxiOff(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppendLog("[维护] 执行 TXI OFF...", Color.Yellow);
|
||||
CometPviClient.TxiOff();
|
||||
AppendLog("[维护] TXI OFF 指令已发送", Color.Lime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[错误] TXI OFF 失败:{ex.Message}", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
|
||||
/// <summary>
|
||||
/// 设置操作类按钮的启用状态
|
||||
/// </summary>
|
||||
private void SetOperationButtonsEnabled(bool enabled)
|
||||
{
|
||||
_btnTurnOn.Enabled = enabled;
|
||||
_btnTurnOff.Enabled = enabled;
|
||||
_btnSetVoltage.Enabled = enabled;
|
||||
_btnSetCurrent.Enabled = enabled;
|
||||
_btnReadVoltage.Enabled = enabled;
|
||||
_btnReadCurrent.Enabled = enabled;
|
||||
_btnReadSystemStatus.Enabled = enabled;
|
||||
_btnReadErrors.Enabled = enabled;
|
||||
_btnWarmUp.Enabled = enabled;
|
||||
_btnTraining.Enabled = enabled;
|
||||
_btnFilamentCalibration.Enabled = enabled;
|
||||
_btnAutoCenter.Enabled = enabled;
|
||||
_btnTxiOn.Enabled = enabled;
|
||||
_btnTxiOff.Enabled = enabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 线程安全地追加日志到 RichTextBox
|
||||
/// </summary>
|
||||
private void AppendLog(string message, Color? color = null)
|
||||
{
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
var timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
|
||||
var logLine = $"[{timestamp}] {message}\n";
|
||||
|
||||
_rtbLog.SelectionStart = _rtbLog.TextLength;
|
||||
_rtbLog.SelectionLength = 0;
|
||||
_rtbLog.SelectionColor = color ?? Color.LightGreen;
|
||||
_rtbLog.AppendText(logLine);
|
||||
_rtbLog.ScrollToCaret();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 线程安全地在 UI 线程执行操作
|
||||
/// </summary>
|
||||
private void SafeInvoke(Action action)
|
||||
{
|
||||
if (this.IsDisposed) return;
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
try { this.Invoke(action); }
|
||||
catch (ObjectDisposedException) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 窗体关闭和退出
|
||||
|
||||
/// <summary>
|
||||
/// 窗体加载后立即隐藏,默认只显示托盘图标
|
||||
/// </summary>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
this.Visible = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.WindowState = FormWindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭窗体时最小化到托盘,不退出应用
|
||||
/// </summary>
|
||||
private void OnFormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (e.CloseReason == CloseReason.UserClosing)
|
||||
{
|
||||
e.Cancel = true;
|
||||
this.Hide();
|
||||
this.ShowInTaskbar = false;
|
||||
_notifyIcon.ShowBalloonTip(1000, "XplorePlane Comet Host",
|
||||
"程序已最小化到系统托盘", ToolTipIcon.Info);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 托盘菜单退出(已禁用,仅提示)
|
||||
/// </summary>
|
||||
private void OnExitClick(object sender, EventArgs e)
|
||||
{
|
||||
MessageBox.Show("XplorePlane Comet Host does not allow manual exit; it will close along with the shutdown of XplorePlane.\r\nXplorePlane Comet Host不允许手动退出,它会跟随XplorePlane的关闭一并退出。", "XplorePlane Comet Host Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制退出按钮点击 — 需要输入密码 Hexagon 才可退出
|
||||
/// Force exit button click — requires password "Hexagon" to exit
|
||||
/// </summary>
|
||||
private void OnForceExitClick(object sender, EventArgs e)
|
||||
{
|
||||
// 使用自定义输入对话框获取密码 | Use custom input dialog to get password
|
||||
using (var dlg = new ForceExitPasswordDialog())
|
||||
{
|
||||
if (dlg.ShowDialog(this) == DialogResult.OK && dlg.EnteredPassword == "Hexagon")
|
||||
{
|
||||
AppendLog("[系统] 强制退出已授权,正在退出... | Force exit authorized, exiting...", Color.Orange);
|
||||
ColseForm(sender, e);
|
||||
}
|
||||
else if (dlg.DialogResult == DialogResult.OK)
|
||||
{
|
||||
// 密码错误 | Wrong password
|
||||
MessageBox.Show("密码错误,无法退出。\r\nIncorrect password, cannot exit.",
|
||||
"XplorePlane Comet Host", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
AppendLog("[警告] 强制退出尝试失败:密码错误 | Force exit attempt failed: wrong password", Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 托盘菜单退出
|
||||
/// </summary>
|
||||
private void ColseForm(object sender, EventArgs e)
|
||||
{
|
||||
CleanupPipe();
|
||||
try { CometPviClient.Dispose(); } catch { }
|
||||
|
||||
if (_notifyIcon != null)
|
||||
{
|
||||
_notifyIcon.Visible = false;
|
||||
_notifyIcon.Dispose();
|
||||
_notifyIcon = null;
|
||||
}
|
||||
|
||||
// 移除 FormClosing 拦截,允许窗体真正关闭
|
||||
this.FormClosing -= OnFormClosing;
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
Reference in New Issue
Block a user