Skip to content

Commit f960653

Browse files
authored
Merge pull request #468 from CreeperAWA/net6
统一字符串资源中的空格和标点符号格式并优化现有功能
2 parents 2fedcd8 + eba6dad commit f960653

41 files changed

Lines changed: 1551 additions & 627 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Ink Canvas/App.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<MenuItem IsCheckable="True" IsChecked="False" Checked="HideICCMainWindowTrayIconMenuItem_Checked" Unchecked="HideICCMainWindowTrayIconMenuItem_UnChecked" Name="HideICCMainWindowTrayIconMenuItem">
1515
<MenuItem.Header>
1616
<ikw:SimpleStackPanel Orientation="Horizontal" Margin="-4,0,0,0">
17-
<TextBlock Name="HideICCMainWindowTrayIconMenuItemHeaderText" FontSize="14" VerticalAlignment="Center" Foreground="#18181b" Text="隐藏ICC主窗口" />
17+
<TextBlock Name="HideICCMainWindowTrayIconMenuItemHeaderText" FontSize="14" VerticalAlignment="Center" Foreground="#18181b" Text="隐藏 ICC-CE 主窗口" />
1818
</ikw:SimpleStackPanel>
1919
</MenuItem.Header>
2020
<MenuItem.Icon>

Ink Canvas/App.xaml.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,11 +1244,11 @@ private async Task RunDeferredStartupTasksAsync()
12441244
{
12451245
try
12461246
{
1247-
await Task.Delay(1200);
1247+
await Task.Delay(400);
12481248

12491249
try
12501250
{
1251-
IACoreDllExtractor.ExtractIACoreDlls();
1251+
await IACoreDllExtractor.ExtractIACoreDllsAsync();
12521252
}
12531253
catch (Exception ex)
12541254
{
@@ -1315,7 +1315,6 @@ private async Task RunDeferredStartupTasksAsync()
13151315

13161316
try
13171317
{
1318-
await Task.Delay(1500);
13191318
DeviceIdentifier.RecordAppLaunch();
13201319
var systemVersion = DeviceIdentifier.GetSystemVersion();
13211320
if (!string.IsNullOrWhiteSpace(systemVersion))
@@ -1404,6 +1403,7 @@ public enum CrashActionType
14041403
private static DateTime startupCompleteHeartbeat = DateTime.MinValue;
14051404
private static DateTime splashScreenStartTime = DateTime.MinValue;
14061405
private static DateTime appStartupStartTime = DateTime.MinValue;
1406+
private static volatile bool isAppExiting = false;
14071407

14081408
/// <summary>
14091409
/// 启动并管理应用的心跳与守护检查定时器,监测启动阶段与主线程是否无响应,并在符合配置的情况下尝试静默重启应用。
@@ -1415,6 +1415,7 @@ public enum CrashActionType
14151415
/// - 对连续重启次数有保护:若重启计数达到或超过5次,会弹出提示并停止自动重启(重置重启计数并退出进程)。
14161416
/// - 在 OOBE(首次引导)展示期间不执行守护检查。
14171417
/// - 该方法会产生外部可观察的副作用:可能启动新进程并调用 Environment.Exit 终止当前进程,或显示消息框。
1418+
/// - 重启前会等待1秒以确保旧进程资源已释放,避免多实例竞争条件。
14181419
/// </remarks>
14191420
private void StartHeartbeatMonitor()
14201421
{
@@ -1427,6 +1428,8 @@ private void StartHeartbeatMonitor()
14271428

14281429
watchdogTimer = new Timer(_ =>
14291430
{
1431+
if (isAppExiting)
1432+
return;
14301433
if (IsOobeShowing)
14311434
return;
14321435

@@ -1491,6 +1494,7 @@ private void StartHeartbeatMonitor()
14911494
try
14921495
{
14931496
string exePath = Process.GetCurrentProcess().MainModule.FileName;
1497+
Thread.Sleep(1000);
14941498
Process.Start(exePath);
14951499
}
14961500
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
@@ -1645,6 +1649,11 @@ internal static string GetDlassTelemetryDsn()
16451649

16461650
private void App_Exit(object sender, ExitEventArgs e)
16471651
{
1652+
isAppExiting = true;
1653+
1654+
try { heartbeatTimer?.Stop(); } catch { }
1655+
try { watchdogTimer?.Change(Timeout.Infinite, Timeout.Infinite); watchdogTimer?.Dispose(); } catch { }
1656+
16481657
CleanupTerminationMonitoring();
16491658

16501659
try
@@ -1656,6 +1665,17 @@ private void App_Exit(object sender, ExitEventArgs e)
16561665
ExceptionHandler.HandleException(ex, "释放 IpcIACoreClient 失败", LogHelper.LogType.Warning);
16571666
}
16581667

1668+
try
1669+
{
1670+
if (mutex != null)
1671+
{
1672+
mutex.ReleaseMutex();
1673+
mutex.Dispose();
1674+
mutex = null;
1675+
}
1676+
}
1677+
catch { }
1678+
16591679
// 卸载所有插件
16601680
try
16611681
{

Ink Canvas/Helpers/AnimationsHelper.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public static void ShowWithFadeIn(UIElement element, double duration = 0.15)
202202
sb.Begin((FrameworkElement)element);
203203
}
204204

205-
public static void ShowWithSlideFromBottomAndFade(UIElement element, double duration = 0.15)
205+
public static void ShowWithSlideFromBottomAndFade(UIElement element, double duration = 0.25)
206206
{
207207
try
208208
{
@@ -211,37 +211,40 @@ public static void ShowWithSlideFromBottomAndFade(UIElement element, double dura
211211

212212
if (element.Visibility == Visibility.Visible) return;
213213

214-
element.Visibility = Visibility.Visible;
215-
216214
var target = ResolveAnimationTarget(element);
217215

216+
// 初始化变换:设置起始位置(从下方20像素开始)
217+
var initialTransform = new TranslateTransform(0, 20);
218+
target.RenderTransform = initialTransform;
219+
target.Opacity = 0;
220+
221+
element.Visibility = Visibility.Visible;
222+
218223
var sb = new Storyboard();
219224

220225
var fadeInAnimation = new DoubleAnimation
221226
{
222-
From = 0.5,
227+
From = 0,
223228
To = 1,
224229
Duration = TimeSpan.FromSeconds(duration)
225230
};
226231
fadeInAnimation.EasingFunction = new CubicEase();
227-
232+
Storyboard.SetTarget(fadeInAnimation, target);
228233
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(UIElement.OpacityProperty));
229234

230235
var slideAnimation = new DoubleAnimation
231236
{
232-
From = 10,
237+
From = 20,
233238
To = 0,
234239
Duration = TimeSpan.FromSeconds(duration)
235240
};
236-
Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
237-
238241
slideAnimation.EasingFunction = new CubicEase();
242+
Storyboard.SetTarget(slideAnimation, target);
243+
Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
239244

240245
sb.Children.Add(fadeInAnimation);
241246
sb.Children.Add(slideAnimation);
242247

243-
target.RenderTransform = new TranslateTransform();
244-
245248
sb.Begin((FrameworkElement)target);
246249
}
247250
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

Ink Canvas/Helpers/AutoUpdateHelper.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,6 @@ public static async Task<List<UpdateLineGroup>> GetAvailableLineGroupsOrdered(Up
445445
continue;
446446
}
447447

448-
LogHelper.WriteLogToFile($"AutoUpdate | 检测线路组: {group.GroupName} ({testUrl})");
449448
testTasks.Add(MeasureLineGroupDelayAsync(group, testUrl));
450449
}
451450

Ink Canvas/Helpers/BaseUploadQueue.cs

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class UploadQueueItem
3131
{
3232
public string FilePath { get; set; }
3333
public int RetryCount { get; set; }
34+
public DateTime AddedTime { get; set; }
3435
}
3536

3637
/// <summary>
@@ -40,6 +41,8 @@ public abstract class BaseUploadQueue : IDisposable
4041
{
4142
protected const int BATCH_SIZE = 10; // 批量上传大小
4243
protected const int MAX_RETRY_COUNT = 3; // 最大重试次数
44+
protected const int MAX_QUEUE_SIZE = 1000; // 队列最大大小限制
45+
protected const int MAX_ITEM_AGE_HOURS = 72; // 队列项最大存活时间(72小时)
4346

4447
/// <summary>
4548
/// 上传队列
@@ -134,6 +137,7 @@ public void InitializeQueue()
134137

135138
int restoredCount = 0;
136139
int skippedCount = 0;
140+
int expiredCount = 0;
137141

138142
foreach (var item in queueData)
139143
{
@@ -144,6 +148,13 @@ public void InitializeQueue()
144148
continue;
145149
}
146150

151+
// 检查队列项是否过期
152+
if ((DateTime.Now - item.AddedTime).TotalHours > MAX_ITEM_AGE_HOURS)
153+
{
154+
expiredCount++;
155+
continue;
156+
}
157+
147158
// 验证文件格式和大小
148159
if (!IsValidFile(item.FilePath))
149160
{
@@ -155,7 +166,8 @@ public void InitializeQueue()
155166
_uploadQueue.Enqueue(new UploadQueueItem
156167
{
157168
FilePath = item.FilePath,
158-
RetryCount = item.RetryCount
169+
RetryCount = item.RetryCount,
170+
AddedTime = item.AddedTime
159171
});
160172
restoredCount++;
161173
}
@@ -164,7 +176,7 @@ public void InitializeQueue()
164176

165177
if (restoredCount > 0)
166178
{
167-
LogHelper.WriteLogToFile($"[{GetType().Name}] 已恢复上传队列:{restoredCount}个文件,跳过{skippedCount}个无效文件", LogHelper.LogType.Event);
179+
LogHelper.WriteLogToFile($"[{GetType().Name}] 已恢复上传队列:{restoredCount}个文件,跳过{skippedCount}个无效文件,过期{expiredCount}个文件", LogHelper.LogType.Event);
168180
// 如果恢复了队列,触发处理
169181
_ = Task.Run(async () =>
170182
{
@@ -178,9 +190,9 @@ public void InitializeQueue()
178190
}
179191
});
180192
}
181-
else if (skippedCount > 0)
193+
else if (skippedCount > 0 || expiredCount > 0)
182194
{
183-
LogHelper.WriteLogToFile($"[{GetType().Name}] 队列恢复完成:跳过{skippedCount}个无效文件", LogHelper.LogType.Event);
195+
LogHelper.WriteLogToFile($"[{GetType().Name}] 队列恢复完成:跳过{skippedCount}个无效文件,过期{expiredCount}个文件", LogHelper.LogType.Event);
184196
}
185197
}
186198
catch (Exception ex)
@@ -215,7 +227,7 @@ protected async Task SaveQueueToFileAsync(CancellationToken cancellationToken =
215227
{
216228
FilePath = item.FilePath,
217229
RetryCount = item.RetryCount,
218-
AddedTime = DateTime.Now
230+
AddedTime = item.AddedTime
219231
});
220232
}
221233

@@ -274,16 +286,70 @@ protected void ClearQueueFile()
274286
}
275287
}
276288

289+
/// <summary>
290+
/// 清理队列中的过期项
291+
/// </summary>
292+
/// <returns>清理的项数</returns>
293+
private int CleanupExpiredItems()
294+
{
295+
int cleanedCount = 0;
296+
var tempItems = new List<UploadQueueItem>();
297+
298+
// 先全部出队
299+
while (_uploadQueue.TryDequeue(out UploadQueueItem item))
300+
{
301+
// 检查是否过期
302+
if ((DateTime.Now - item.AddedTime).TotalHours <= MAX_ITEM_AGE_HOURS)
303+
{
304+
tempItems.Add(item);
305+
}
306+
else
307+
{
308+
cleanedCount++;
309+
}
310+
}
311+
312+
// 重新入队未过期项
313+
foreach (var item in tempItems)
314+
{
315+
_uploadQueue.Enqueue(item);
316+
}
317+
318+
if (cleanedCount > 0)
319+
{
320+
LogHelper.WriteLogToFile($"[{GetType().Name}] 清理{cleanedCount}个过期队列项", LogHelper.LogType.Event);
321+
}
322+
323+
return cleanedCount;
324+
}
325+
277326
/// <summary>
278327
/// 将文件加入上传队列
279328
/// </summary>
280329
protected void EnqueueFile(string filePath, int retryCount = 0, CancellationToken cancellationToken = default)
281330
{
282-
_uploadQueue.Enqueue(new UploadQueueItem
331+
var newItem = new UploadQueueItem
283332
{
284333
FilePath = filePath,
285-
RetryCount = retryCount
286-
});
334+
RetryCount = retryCount,
335+
AddedTime = DateTime.Now
336+
};
337+
338+
// 队列大小检查,防止无限增长
339+
if (_uploadQueue.Count >= MAX_QUEUE_SIZE)
340+
{
341+
// 先尝试清理过期项
342+
int cleanedCount = CleanupExpiredItems();
343+
344+
// 清理后仍然满,则记录警告并跳过
345+
if (_uploadQueue.Count >= MAX_QUEUE_SIZE)
346+
{
347+
LogHelper.WriteLogToFile($"[{GetType().Name}] 队列已满({MAX_QUEUE_SIZE}),清理{cleanedCount}个过期项后仍满,跳过入队: {Path.GetFileName(filePath)}", LogHelper.LogType.Warning);
348+
return;
349+
}
350+
}
351+
352+
_uploadQueue.Enqueue(newItem);
287353

288354
// 异步保存队列到文件
289355
_ = Task.Run(async () =>

Ink Canvas/Helpers/ComPPTLinkManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public bool SkipAnimationsWhenNavigating
6060
/// <summary>
6161
/// 停止对 PowerPoint 的监控,断开当前连接并停止触发相关事件。
6262
/// </summary>
63-
public void StopMonitoring() => _inner.StopMonitoring();
63+
public void StopMonitoring(bool isShutdown = false) => _inner.StopMonitoring(isShutdown);
6464

6565
/// <summary>
6666
/// 强制断开当前 COM PPT 连接并停止对其监控,同时写入事件日志。

Ink Canvas/Helpers/IACoreDllExtractor.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using System;
1+
using System;
22
using System.IO;
33
using System.Reflection;
4+
using System.Threading.Tasks;
45

56
namespace Ink_Canvas.Helpers
67
{
@@ -19,7 +20,7 @@ public static class IACoreDllExtractor
1920
/// <summary>
2021
/// 在应用启动时释放IACore相关DLL
2122
/// </summary>
22-
public static void ExtractIACoreDlls()
23+
public static async Task ExtractIACoreDllsAsync()
2324
{
2425
try
2526
{
@@ -38,7 +39,7 @@ public static void ExtractIACoreDlls()
3839
}
3940

4041
// 从嵌入资源中释放DLL
41-
if (ExtractDllFromResource(dllName, targetPath))
42+
if (await ExtractDllFromResourceAsync(dllName, targetPath))
4243
{
4344
LogHelper.WriteLogToFile($"成功释放 {dllName}{targetPath}");
4445
}
@@ -59,7 +60,7 @@ public static void ExtractIACoreDlls()
5960
/// <summary>
6061
/// 从嵌入资源中提取DLL文件
6162
/// </summary>
62-
private static bool ExtractDllFromResource(string dllName, string targetPath)
63+
private static async Task<bool> ExtractDllFromResourceAsync(string dllName, string targetPath)
6364
{
6465
try
6566
{
@@ -81,10 +82,10 @@ private static bool ExtractDllFromResource(string dllName, string targetPath)
8182
Directory.CreateDirectory(targetDirectory);
8283
}
8384

84-
// 写入文件
85-
using (FileStream fileStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
85+
// 异步写入文件
86+
using (FileStream fileStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None, 81920, useAsync: true))
8687
{
87-
resourceStream.CopyTo(fileStream);
88+
await resourceStream.CopyToAsync(fileStream);
8889
}
8990

9091
return true;

Ink Canvas/Helpers/IPPTLinkManager.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ public interface IPPTLinkManager : IDisposable
2424
/// 开始监视与 PowerPoint 的连接以及幻灯片放映相关状态,并在状态变化时触发对应事件。
2525
/// </summary>
2626
void StartMonitoring();
27-
/// <summary>
28-
/// 停止监控 PowerPoint 的连接与事件,停止接收并处理与演示文稿和幻灯片放映相关的通知。
29-
/// </summary>
30-
void StopMonitoring();
27+
void StopMonitoring(bool isShutdown = false);
3128

3229
/// <summary>
3330
/// 重新加载或重建与 PowerPoint 的连接。

0 commit comments

Comments
 (0)