增加开机自启配置

This commit is contained in:
XingCheng3
2026-05-16 14:50:22 +08:00
parent 9aaa9a97e9
commit 3b871f24b3
3 changed files with 286 additions and 6 deletions

View File

@@ -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)
{

View File

@@ -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
/// </summary>
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
}
}
/// <summary>
/// 构建开机自启设置区域状态直接读取Windows当前用户启动项。
/// </summary>
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();
}
/// <summary>
/// 动态构建单个扫码枪面板的控件
/// </summary>
@@ -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 =
$@"<?xml version=""1.0"" encoding=""UTF-16""?>
<Task version=""1.2"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task"">
<RegistrationInfo>
<Description>潍柴称重工控机程序开机自启</Description>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<Delay>PT30S</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id=""Author"">
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context=""Author"">
<Exec>
<Command>{SecurityElement.Escape(exePath)}</Command>
<WorkingDirectory>{SecurityElement.Escape(workDir)}</WorkingDirectory>
</Exec>
</Actions>
</Task>";
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();