diff --git a/App.xaml.cs b/App.xaml.cs
index d7b2f21..bf033df 100644
--- a/App.xaml.cs
+++ b/App.xaml.cs
@@ -34,7 +34,8 @@ namespace DrillTools
// 防止选择窗口关闭后触发 OnLastWindowClose 导致应用退出
ShutdownMode = ShutdownMode.OnExplicitShutdown;
- var selectionWindow = new StartupSelectionWindow(filePath);
+ bool canClearParameters = CanClearDrillTapeParameters(filePath);
+ var selectionWindow = new StartupSelectionWindow(filePath, canClearParameters);
selectionWindow.ShowDialog();
switch (selectionWindow.SelectedAction)
@@ -47,6 +48,10 @@ namespace DrillTools
PerformHeadlessExport(filePath);
Shutdown();
break;
+ case StartupAction.ClearParameters:
+ PerformParameterCleanup(filePath);
+ Shutdown();
+ break;
default:
Shutdown();
break;
@@ -97,6 +102,37 @@ namespace DrillTools
}
}
+ private static bool CanClearDrillTapeParameters(string filePath)
+ {
+ try
+ {
+ string content = CommandTypeFileReader.ReadAllText(filePath);
+ return DrillTapeParameterCleaner.CanClearParameters(content);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ private static void PerformParameterCleanup(string filePath)
+ {
+ try
+ {
+ DrillTapeParameterCleaner.ClearParametersAndSave(filePath);
+ System.Windows.MessageBox.Show(
+ $"参数已清空,原文件已备份为:\n{Path.GetFileName(filePath)}.bak",
+ "清空参数完成",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"清空参数失败:\n{ex.Message}",
+ "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
///
/// 验证是否为有效的钻带文件
///
diff --git a/DrillTapeParameterCleaner.cs b/DrillTapeParameterCleaner.cs
new file mode 100644
index 0000000..a43d782
--- /dev/null
+++ b/DrillTapeParameterCleaner.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace DrillTools
+{
+ internal static class DrillTapeParameterCleaner
+ {
+ private const int Gb2312CodePage = 936;
+ private static readonly char[] LineEndChars = { '\r', '\n' };
+ private static readonly Regex HeaderToolDefinitionStartPattern = new(
+ @"^T\d+C",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static readonly Regex ToolDefinitionPattern = new(
+ @"^(?\s*T\d+C\d+(?:\.\d+)?)(?H.+)$",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase);
+
+ public static bool CanClearParameters(string drillTapeContent)
+ {
+ var lines = SplitLines(drillTapeContent);
+ if (lines.Count < 2)
+ return false;
+
+ string secondLine = lines[1].Text.Trim();
+ if (!secondLine.StartsWith(";") || secondLine.Length == 1)
+ return false;
+
+ var toolDefinitionLines = GetHeaderToolDefinitionLines(lines);
+ if (toolDefinitionLines.Count == 0)
+ return false;
+
+ foreach (var line in toolDefinitionLines)
+ {
+ if (!ToolDefinitionPattern.IsMatch(line.Text.TrimEnd()))
+ return false;
+ }
+
+ return true;
+ }
+
+ public static string ClearParameters(string drillTapeContent)
+ {
+ if (!CanClearParameters(drillTapeContent))
+ throw new InvalidOperationException("钻带文件不符合清空参数条件");
+
+ var lines = SplitLines(drillTapeContent);
+ var builder = new StringBuilder(drillTapeContent.Length);
+
+ for (int i = 0; i < lines.Count; i++)
+ {
+ if (i == 1)
+ continue;
+
+ string text = lines[i].Text;
+ var match = ToolDefinitionPattern.Match(text.TrimEnd());
+ if (match.Success && IsBeforeHeaderEnd(lines, i))
+ {
+ int trailingWhitespaceLength = text.Length - text.TrimEnd().Length;
+ string trailingWhitespace = trailingWhitespaceLength > 0 ? text[^trailingWhitespaceLength..] : string.Empty;
+ text = match.Groups["prefix"].Value + trailingWhitespace;
+ }
+
+ builder.Append(text);
+ builder.Append(lines[i].LineEnding);
+ }
+
+ return builder.ToString();
+ }
+
+ public static void ClearParametersAndSave(string filePath)
+ {
+ string content = CommandTypeFileReader.ReadAllText(filePath);
+ string cleanedContent = ClearParameters(content);
+
+ string backupFilePath = filePath + ".bak";
+ File.Copy(filePath, backupFilePath, true);
+
+ using var writer = new StreamWriter(filePath, false, CreateAnsiEncoding());
+ writer.Write(cleanedContent);
+ }
+
+ private static List SplitLines(string content)
+ {
+ var lines = new List();
+ int index = 0;
+
+ while (index < content.Length)
+ {
+ int lineEndIndex = content.IndexOfAny(LineEndChars, index);
+ if (lineEndIndex < 0)
+ {
+ lines.Add(new DrillTapeLine(content[index..], string.Empty));
+ return lines;
+ }
+
+ string text = content[index..lineEndIndex];
+ string lineEnding;
+ if (content[lineEndIndex] == '\r' && lineEndIndex + 1 < content.Length && content[lineEndIndex + 1] == '\n')
+ {
+ lineEnding = "\r\n";
+ index = lineEndIndex + 2;
+ }
+ else
+ {
+ lineEnding = content[lineEndIndex].ToString();
+ index = lineEndIndex + 1;
+ }
+
+ lines.Add(new DrillTapeLine(text, lineEnding));
+ }
+
+ if (content.Length == 0)
+ lines.Add(new DrillTapeLine(string.Empty, string.Empty));
+
+ return lines;
+ }
+
+ private static List GetHeaderToolDefinitionLines(IReadOnlyList lines)
+ {
+ var toolDefinitionLines = new List();
+
+ foreach (var line in lines)
+ {
+ string trimmedLine = line.Text.Trim();
+ if (trimmedLine == "%")
+ break;
+
+ if (HeaderToolDefinitionStartPattern.IsMatch(trimmedLine))
+ toolDefinitionLines.Add(line);
+ }
+
+ return toolDefinitionLines;
+ }
+
+ private static bool IsBeforeHeaderEnd(IReadOnlyList lines, int lineIndex)
+ {
+ for (int i = 0; i < lineIndex; i++)
+ {
+ if (lines[i].Text.Trim() == "%")
+ return false;
+ }
+
+ return true;
+ }
+
+ private static Encoding CreateAnsiEncoding()
+ {
+ try
+ {
+ return Encoding.GetEncoding(Gb2312CodePage);
+ }
+ catch
+ {
+ return Encoding.Default;
+ }
+ }
+
+ private readonly record struct DrillTapeLine(string Text, string LineEnding);
+ }
+}
diff --git a/StartupSelectionWindow.xaml b/StartupSelectionWindow.xaml
index a4192df..b002d92 100644
--- a/StartupSelectionWindow.xaml
+++ b/StartupSelectionWindow.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="选择功能"
- Width="300"
+ Width="430"
SizeToContent="Height"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
@@ -18,7 +18,8 @@
-
+
+
diff --git a/StartupSelectionWindow.xaml.cs b/StartupSelectionWindow.xaml.cs
index f9494b2..6cd8875 100644
--- a/StartupSelectionWindow.xaml.cs
+++ b/StartupSelectionWindow.xaml.cs
@@ -7,17 +7,19 @@ namespace DrillTools
{
None,
AdjustToolOrder,
- ExportHoleCount
+ ExportHoleCount,
+ ClearParameters
}
public partial class StartupSelectionWindow : Window
{
public StartupAction SelectedAction { get; private set; } = StartupAction.None;
- public StartupSelectionWindow(string filePath)
+ public StartupSelectionWindow(string filePath, bool canClearParameters = false)
{
InitializeComponent();
DataContext = new { FileName = Path.GetFileName(filePath) };
+ ClearParametersButton.Visibility = canClearParameters ? Visibility.Visible : Visibility.Collapsed;
}
private void AdjustToolOrder_Click(object sender, RoutedEventArgs e)
@@ -31,5 +33,11 @@ namespace DrillTools
SelectedAction = StartupAction.ExportHoleCount;
Close();
}
+
+ private void ClearParameters_Click(object sender, RoutedEventArgs e)
+ {
+ SelectedAction = StartupAction.ClearParameters;
+ Close();
+ }
}
}