diff --git a/SCADA/App.config b/SCADA/App.config index ac6d2ff..600fda6 100644 --- a/SCADA/App.config +++ b/SCADA/App.config @@ -30,12 +30,12 @@ - - - - - - + + + + + + diff --git a/SCADA/Core/AppConfig.cs b/SCADA/Core/AppConfig.cs index 4c3d389..fb5b7cd 100644 --- a/SCADA/Core/AppConfig.cs +++ b/SCADA/Core/AppConfig.cs @@ -170,6 +170,8 @@ namespace MesWork [STAThread] static void Main() { + Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory; + new System.Threading.Mutex(true, $"MES_PWT_A95", out bool bCanRun); if (!bCanRun) { diff --git a/SCADA/Pages/UC_SystemSettings.cs b/SCADA/Pages/UC_SystemSettings.cs index 1b0d5f8..8e8a033 100644 --- a/SCADA/Pages/UC_SystemSettings.cs +++ b/SCADA/Pages/UC_SystemSettings.cs @@ -1,7 +1,11 @@ using System; +using System.Diagnostics; using System.Drawing; +using System.IO; +using System.Security; using System.Threading.Tasks; using System.Windows.Forms; +using Microsoft.Win32; namespace MesWork.Pages { @@ -10,6 +14,13 @@ namespace MesWork.Pages /// public partial class UC_SystemSettings : UserControl { + private const string AutoStartKeyName = "WC_GKJ_OIL"; + private const string AutoStartRunKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Run"; + private const string AutoStartTaskName = "WC_GKJ_OIL_AutoStart"; + private bool _isLoadingAutoStart; + private CheckBox chk_AutoStart; + private Label lbl_AutoStartStatus; + // 工位1控件 private ComboBox cmb_Com1; private Button btn_Connect1, btn_Disconnect1, btn_ManualSend1; @@ -32,6 +43,7 @@ namespace MesWork.Pages grp_Station2.Text = $" 工位2({station2}) "; grp_Scanner1.Text = $" {station1} 扫码枪 "; grp_Scanner2.Text = $" {station2} 扫码枪 "; + BuildAutoStartPanel(); if (BarcodeManager.IsEnabled) { @@ -52,6 +64,46 @@ namespace MesWork.Pages } } + /// + /// 构建开机自启设置区域,状态直接读取Windows当前用户启动项。 + /// + private void BuildAutoStartPanel() + { + var grpAutoStart = new GroupBox + { + Text = " 开机自启 ", + Font = new Font("微软雅黑", 12F, FontStyle.Bold), + ForeColor = Color.FromArgb(30, 58, 95), + Location = new Point(30, 410), + Size = new Size(840, 120) + }; + + chk_AutoStart = new CheckBox + { + Text = "启用开机自启", + Font = new Font("微软雅黑", 11F, FontStyle.Bold), + ForeColor = Color.FromArgb(31, 41, 55), + Location = new Point(24, 36), + AutoSize = true, + Cursor = Cursors.Hand + }; + chk_AutoStart.CheckedChanged += chk_AutoStart_CheckedChanged; + grpAutoStart.Controls.Add(chk_AutoStart); + + lbl_AutoStartStatus = new Label + { + Text = "--", + Font = new Font("微软雅黑", 10F), + ForeColor = Color.FromArgb(75, 85, 99), + Location = new Point(24, 72), + AutoSize = true + }; + grpAutoStart.Controls.Add(lbl_AutoStartStatus); + + Controls.Add(grpAutoStart); + RefreshAutoStartState(); + } + /// /// 动态构建单个扫码枪面板的控件 /// @@ -144,6 +196,232 @@ namespace MesWork.Pages // ── 操作方法 ── + private string GetAutoStartCommand() + { + return Application.ExecutablePath; + } + + private bool RunSchtasks(string arguments, out string output) + { + output = ""; + try + { + var psi = new ProcessStartInfo + { + FileName = "schtasks.exe", + Arguments = arguments, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + using (Process process = Process.Start(psi)) + { + output = process.StandardOutput.ReadToEnd() + process.StandardError.ReadToEnd(); + process.WaitForExit(); + return process.ExitCode == 0; + } + } + catch (Exception ex) + { + output = ex.Message; + return false; + } + } + + private bool TryGetAutoStartTaskXml(out string taskXml, out string errMsg) + { + taskXml = ""; + errMsg = ""; + if (RunSchtasks($"/Query /TN \"{AutoStartTaskName}\" /XML", out string output)) + { + taskXml = output; + return true; + } + + if (IsTaskNotFoundOutput(output)) + { + return true; + } + + errMsg = output; + return false; + } + + private bool IsTaskNotFoundOutput(string output) + { + return output.IndexOf("cannot find", StringComparison.OrdinalIgnoreCase) >= 0 || + output.Contains("找不到") || + output.Contains("不存在"); + } + + private void DeleteLegacyRegistryAutoStart() + { + try + { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey(AutoStartRunKeyPath, true)) + { + key?.DeleteValue(AutoStartKeyName, false); + } + } + catch + { + } + } + + private bool TryCreateAutoStartTask(out string errMsg) + { + errMsg = ""; + string xmlPath = Path.Combine(Path.GetTempPath(), $"{AutoStartTaskName}.xml"); + string exePath = GetAutoStartCommand(); + string workDir = Path.GetDirectoryName(exePath); + string taskXml = +$@" + + + 潍柴称重工控机程序开机自启 + + + + true + PT30S + + + + + InteractiveToken + HighestAvailable + + + + IgnoreNew + false + false + true + true + false + + false + false + + true + true + false + false + false + PT0S + 7 + + + + {SecurityElement.Escape(exePath)} + {SecurityElement.Escape(workDir)} + + +"; + + try + { + File.WriteAllText(xmlPath, taskXml, System.Text.Encoding.Unicode); + if (RunSchtasks($"/Create /TN \"{AutoStartTaskName}\" /XML \"{xmlPath}\" /F", out string output)) + { + DeleteLegacyRegistryAutoStart(); + return true; + } + errMsg = output; + return false; + } + catch (Exception ex) + { + errMsg = ex.Message; + return false; + } + finally + { + try { if (File.Exists(xmlPath)) File.Delete(xmlPath); } catch { } + } + } + + private bool IsCurrentProgramAutoStart(string taskXml) + { + return !string.IsNullOrWhiteSpace(taskXml) && + taskXml.IndexOf(GetAutoStartCommand(), StringComparison.OrdinalIgnoreCase) >= 0; + } + + private bool TrySetAutoStart(bool enabled, out string errMsg) + { + errMsg = ""; + if (enabled) + { + return TryCreateAutoStartTask(out errMsg); + } + + DeleteLegacyRegistryAutoStart(); + if (RunSchtasks($"/Delete /TN \"{AutoStartTaskName}\" /F", out string output)) + { + return true; + } + + if (IsTaskNotFoundOutput(output)) + { + return true; + } + + errMsg = output; + return false; + } + + private void RefreshAutoStartState() + { + if (chk_AutoStart == null || lbl_AutoStartStatus == null) return; + + _isLoadingAutoStart = true; + try + { + if (!TryGetAutoStartTaskXml(out string taskXml, out string errMsg)) + { + chk_AutoStart.Checked = false; + lbl_AutoStartStatus.Text = $"读取任务计划失败:{errMsg}"; + lbl_AutoStartStatus.ForeColor = Color.FromArgb(239, 68, 68); + return; + } + + bool isCurrentProgramAutoStart = IsCurrentProgramAutoStart(taskXml); + chk_AutoStart.Checked = isCurrentProgramAutoStart; + if (isCurrentProgramAutoStart) + { + lbl_AutoStartStatus.Text = $"已启用任务计划:{Application.ExecutablePath}"; + lbl_AutoStartStatus.ForeColor = Color.FromArgb(16, 185, 129); + } + else if (string.IsNullOrWhiteSpace(taskXml)) + { + lbl_AutoStartStatus.Text = "未启用"; + lbl_AutoStartStatus.ForeColor = Color.FromArgb(107, 114, 128); + } + else + { + lbl_AutoStartStatus.Text = "任务计划存在但路径不是当前程序,请重新勾选修正"; + lbl_AutoStartStatus.ForeColor = Color.FromArgb(245, 158, 11); + } + } + finally + { + _isLoadingAutoStart = false; + } + } + + private void chk_AutoStart_CheckedChanged(object sender, EventArgs e) + { + if (_isLoadingAutoStart) return; + + bool enabled = chk_AutoStart.Checked; + if (!TrySetAutoStart(enabled, out string errMsg)) + { + MessageBox.Show($"开机自启设置失败:{errMsg}", "设置失败", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + RefreshAutoStartState(); + } + private void DoConnect(string opName, ComboBox cmb) { string com = cmb.SelectedItem?.ToString();