+68
-11
@@ -37,23 +37,65 @@ namespace Ink_Canvas
|
||||
|
||||
public App()
|
||||
{
|
||||
// 如果是看门狗子进程,直接进入看门狗主循环并终止主流程
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
if (args.Length >= 2 && args[1] == "--watchdog")
|
||||
{
|
||||
RunWatchdogIfNeeded();
|
||||
Environment.Exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 启动时优先同步设置,确保CrashAction为最新
|
||||
SyncCrashActionFromSettings();
|
||||
|
||||
this.Startup += new StartupEventHandler(App_Startup);
|
||||
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||
StartHeartbeatMonitor();
|
||||
StartWatchdogIfNeeded();
|
||||
|
||||
// 仅在崩溃后操作为静默重启时才启动看门狗
|
||||
if (CrashAction == CrashActionType.SilentRestart)
|
||||
{
|
||||
StartWatchdogIfNeeded();
|
||||
}
|
||||
this.Exit += App_Exit; // 注册退出事件
|
||||
}
|
||||
|
||||
// 增加字段保存崩溃后操作设置
|
||||
public static CrashActionType CrashAction = CrashActionType.SilentRestart;
|
||||
|
||||
// 修正:允许静态调用
|
||||
public static void SyncCrashActionFromSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 优先从 Settings.json 直接读取
|
||||
var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.json");
|
||||
if (File.Exists(settingsPath))
|
||||
{
|
||||
var json = File.ReadAllText(settingsPath);
|
||||
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
|
||||
int crashAction = 0;
|
||||
try { crashAction = (int)(obj["startup"]["crashAction"] ?? 0); } catch { }
|
||||
CrashAction = (CrashActionType)crashAction;
|
||||
}
|
||||
// 兜底:从主窗口同步
|
||||
else if (Ink_Canvas.MainWindow.Settings != null && Ink_Canvas.MainWindow.Settings.Startup != null)
|
||||
{
|
||||
CrashAction = (CrashActionType)Ink_Canvas.MainWindow.Settings.Startup.CrashAction;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
Ink_Canvas.MainWindow.ShowNewMessage("抱歉,出现未预期的异常,可能导致 InkCanvasForClass 运行不稳定。\n建议保存墨迹后重启应用。", true);
|
||||
LogHelper.NewLog(e.Exception.ToString());
|
||||
e.Handled = true;
|
||||
|
||||
// 修改:仅当非用户主动退出时才触发自动重启
|
||||
SyncCrashActionFromSettings(); // 新增:崩溃时同步最新设置
|
||||
|
||||
if (CrashAction == CrashActionType.SilentRestart && !IsAppExitByUser)
|
||||
{
|
||||
StartupCount.Increment();
|
||||
@@ -78,7 +120,6 @@ namespace Ink_Canvas
|
||||
|
||||
void App_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
RunWatchdogIfNeeded();
|
||||
/*if (!StoreHelper.IsStoreApp) */RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
||||
|
||||
LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version.ToString()));
|
||||
@@ -91,6 +132,16 @@ namespace Ink_Canvas
|
||||
LogHelper.NewLog("Detected existing instance");
|
||||
MessageBox.Show("已有一个程序实例正在运行");
|
||||
LogHelper.NewLog("Ink Canvas automatically closed");
|
||||
IsAppExitByUser = true; // 多开时标记为用户主动退出
|
||||
// 写入退出信号,确保看门狗不会重启
|
||||
try {
|
||||
StartupCount.Reset();
|
||||
File.WriteAllText(watchdogExitSignalFile, "exit");
|
||||
if (watchdogProcess != null && !watchdogProcess.HasExited)
|
||||
{
|
||||
watchdogProcess.Kill();
|
||||
}
|
||||
} catch { }
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
@@ -260,6 +311,7 @@ namespace Ink_Canvas
|
||||
if ((DateTime.Now - lastHeartbeat).TotalSeconds > 10)
|
||||
{
|
||||
LogHelper.NewLog("检测到主线程无响应,自动重启。");
|
||||
SyncCrashActionFromSettings(); // 新增:心跳检测时同步最新设置
|
||||
if (CrashAction == CrashActionType.SilentRestart)
|
||||
{
|
||||
StartupCount.Increment();
|
||||
@@ -320,16 +372,21 @@ namespace Ink_Canvas
|
||||
}
|
||||
Thread.Sleep(2000);
|
||||
}
|
||||
// 主进程异常退出,自动重启
|
||||
StartupCount.Increment();
|
||||
if (StartupCount.GetCount() >= 5)
|
||||
// 主进程异常退出,自动重启前判断崩溃后操作
|
||||
SyncCrashActionFromSettings(); // 新增:同步设置
|
||||
if (CrashAction == CrashActionType.SilentRestart)
|
||||
{
|
||||
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
StartupCount.Reset();
|
||||
Environment.Exit(1);
|
||||
StartupCount.Increment();
|
||||
if (StartupCount.GetCount() >= 5)
|
||||
{
|
||||
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
StartupCount.Reset();
|
||||
Environment.Exit(1);
|
||||
}
|
||||
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
Process.Start(exePath);
|
||||
}
|
||||
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
Process.Start(exePath);
|
||||
// CrashActionType.NoAction 时不重启,直接退出
|
||||
}
|
||||
catch { }
|
||||
Environment.Exit(0);
|
||||
|
||||
@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.0.3")]
|
||||
[assembly: AssemblyFileVersion("1.7.0.3")]
|
||||
[assembly: AssemblyVersion("1.7.0.4")]
|
||||
[assembly: AssemblyFileVersion("1.7.0.4")]
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
@@ -576,358 +577,162 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CopyDirectory(string sourceDir, string destinationDir)
|
||||
private static async Task<long> GetUrlDelay(string url)
|
||||
{
|
||||
bool allCopiesSuccessful = true;
|
||||
|
||||
try
|
||||
{
|
||||
// 创建目标目录(如果不存在)
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Created/verified destination directory: {destinationDir}");
|
||||
|
||||
// 复制所有文件
|
||||
foreach (string filePath in Directory.GetFiles(sourceDir))
|
||||
using (var client = new System.Net.Http.HttpClient())
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
string destPath = Path.Combine(destinationDir, fileName);
|
||||
try
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Copying file: {fileName}");
|
||||
|
||||
// 如果目标文件存在,先删除
|
||||
if (File.Exists(destPath))
|
||||
{
|
||||
File.Delete(destPath);
|
||||
}
|
||||
|
||||
File.Copy(filePath, destPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
allCopiesSuccessful = false;
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error copying file {fileName}: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
client.Timeout = TimeSpan.FromSeconds(5);
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var resp = await client.SendAsync(new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Head, url));
|
||||
sw.Stop();
|
||||
if (resp.IsSuccessStatusCode)
|
||||
return sw.ElapsedMilliseconds;
|
||||
}
|
||||
|
||||
// 递归复制所有子目录
|
||||
foreach (string subDirPath in Directory.GetDirectories(sourceDir))
|
||||
{
|
||||
string subDirName = Path.GetFileName(subDirPath);
|
||||
string destSubDir = Path.Combine(destinationDir, subDirName);
|
||||
|
||||
bool subDirCopyResult = CopyDirectory(subDirPath, destSubDir);
|
||||
if (!subDirCopyResult)
|
||||
{
|
||||
allCopiesSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
return allCopiesSuccessful;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error copying directory {sourceDir}: {ex.Message}", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
catch { }
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void RestartApplication()
|
||||
// 线路组结构体(包含版本、下载、日志地址)
|
||||
public class UpdateLineGroup
|
||||
{
|
||||
public string GroupName { get; set; } // 组名
|
||||
public string VersionUrl { get; set; } // 版本检测地址
|
||||
public string DownloadUrlFormat { get; set; } // 下载地址格式(带{0}占位符)
|
||||
public string LogUrl { get; set; } // 更新日志地址
|
||||
}
|
||||
|
||||
// 通道-线路组映射
|
||||
private static readonly Dictionary<UpdateChannel, List<UpdateLineGroup>> ChannelLineGroups = new Dictionary<UpdateChannel, List<UpdateLineGroup>>
|
||||
{
|
||||
{ UpdateChannel.Release, new List<UpdateLineGroup>
|
||||
{
|
||||
new UpdateLineGroup
|
||||
{
|
||||
GroupName = "GitHub主线",
|
||||
VersionUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt",
|
||||
DownloadUrlFormat = "https://github.com/InkCanvasForClass/community/releases/download/{0}/InkCanvasForClass.CE.{0}.zip",
|
||||
LogUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/UpdateLog.md"
|
||||
},
|
||||
new UpdateLineGroup
|
||||
{
|
||||
GroupName = "bgithub备用",
|
||||
VersionUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt",
|
||||
DownloadUrlFormat = "https://bgithub.xyz/InkCanvasForClass/community/releases/download/{0}/InkCanvasForClass.CE.{0}.zip",
|
||||
LogUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/UpdateLog.md"
|
||||
}
|
||||
}
|
||||
},
|
||||
{ UpdateChannel.Beta, new List<UpdateLineGroup>
|
||||
{
|
||||
new UpdateLineGroup
|
||||
{
|
||||
GroupName = "GitHub主线",
|
||||
VersionUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt",
|
||||
DownloadUrlFormat = "https://github.com/InkCanvasForClass/community-beta/releases/download/{0}/InkCanvasForClass.CE.{0}.zip",
|
||||
LogUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.md"
|
||||
},
|
||||
new UpdateLineGroup
|
||||
{
|
||||
GroupName = "bgithub备用",
|
||||
VersionUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt",
|
||||
DownloadUrlFormat = "https://bgithub.xyz/InkCanvasForClass/community-beta/releases/download/{0}/InkCanvasForClass.CE.{0}.zip",
|
||||
LogUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 检测线路组延迟,只检测当前通道下的所有线路组,返回最快组
|
||||
private static async Task<UpdateLineGroup> GetFastestLineGroup(UpdateChannel channel)
|
||||
{
|
||||
var groups = ChannelLineGroups[channel];
|
||||
long minDelay = long.MaxValue;
|
||||
UpdateLineGroup bestGroup = null;
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var delay = await GetUrlDelay(group.VersionUrl);
|
||||
if (delay >= 0 && delay < minDelay)
|
||||
{
|
||||
minDelay = delay;
|
||||
bestGroup = group;
|
||||
}
|
||||
}
|
||||
return bestGroup;
|
||||
}
|
||||
|
||||
// 新的自动选择线路组的更新检测方法,返回远程版本号和所用线路组
|
||||
public static async Task<(string remoteVersion, UpdateLineGroup lineGroup)> CheckForUpdatesWithAutoLine(UpdateChannel channel = UpdateChannel.Release, bool alwaysGetRemote = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
string appPath = Assembly.GetExecutingAssembly().Location;
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Restarting application: {appPath}");
|
||||
|
||||
// Create a batch file to wait briefly and then start the application
|
||||
// This allows the current process to fully exit before starting the new instance
|
||||
string batchFilePath = Path.Combine(Path.GetTempPath(), "RestartICC_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat");
|
||||
|
||||
string batchContent =
|
||||
"@echo off\r\n" +
|
||||
"timeout /t 2 /nobreak >nul\r\n" +
|
||||
":: 检查应用程序是否已经在运行\r\n" +
|
||||
"tasklist /FI \"IMAGENAME eq Ink Canvas.exe\" | find /i \"Ink Canvas.exe\" > nul\r\n" +
|
||||
"if %ERRORLEVEL% neq 0 (\r\n" +
|
||||
" echo 启动应用程序...\r\n" +
|
||||
$" start \"\" \"{appPath}\"\r\n" +
|
||||
") else (\r\n" +
|
||||
" echo 应用程序已经在运行,不再重复启动\r\n" +
|
||||
")\r\n" +
|
||||
"timeout /t 1 /nobreak >nul\r\n" +
|
||||
"del \"%~f0\"\r\n" +
|
||||
"exit\r\n"; // 确保批处理进程结束
|
||||
|
||||
File.WriteAllText(batchFilePath, batchContent);
|
||||
|
||||
// Start the batch file
|
||||
Process.Start(new ProcessStartInfo
|
||||
string localVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Local version: {localVersion}");
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 检测通道 {channel} 下最快线路组...");
|
||||
var bestGroup = await GetFastestLineGroup(channel);
|
||||
if (bestGroup == null)
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/c start \"\" \"{batchFilePath}\"",
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false
|
||||
});
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Created restart script at {batchFilePath}");
|
||||
|
||||
// Shutdown the application
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Shutting down application for restart");
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均不可用", LogHelper.LogType.Error);
|
||||
return (null, null);
|
||||
}
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 选择最快线路组: {bestGroup.GroupName} {bestGroup.VersionUrl}");
|
||||
string remoteVersion = await GetRemoteVersion(bestGroup.VersionUrl);
|
||||
if (remoteVersion != null)
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error restarting application: {ex.Message}", LogHelper.LogType.Error);
|
||||
|
||||
// Fallback direct restart approach
|
||||
try
|
||||
{
|
||||
string appPath = Assembly.GetExecutingAssembly().Location;
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Attempting direct restart: {appPath}");
|
||||
|
||||
// 检查是否已有实例运行
|
||||
Process[] processes = Process.GetProcessesByName("Ink Canvas");
|
||||
if (processes.Length <= 1) // 只有当前进程
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Remote version: {remoteVersion}");
|
||||
Version local = new Version(localVersion);
|
||||
Version remote = new Version(remoteVersion);
|
||||
if (remote > local || alwaysGetRemote)
|
||||
{
|
||||
Process.Start(appPath);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | New version available or alwaysGetRemote: {remoteVersion}");
|
||||
return (remoteVersion, bestGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Application already running, not starting a new instance");
|
||||
}
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
}
|
||||
catch (Exception fallbackEx)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Fallback restart also failed: {fallbackEx.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExecuteCommandLine(string command)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo processStartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/c {command} & exit", // 添加exit确保cmd进程退出
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using (Process process = new Process { StartInfo = processStartInfo })
|
||||
{
|
||||
process.Start();
|
||||
// 设置一个超时时间
|
||||
bool exited = process.WaitForExit(500); // 等待500毫秒
|
||||
if (!exited)
|
||||
{
|
||||
// 不等待进程完成,让它在后台运行
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Command is running in background");
|
||||
}
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error executing command: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteUpdatesFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(updatesFolderPath))
|
||||
{
|
||||
// Try to delete all files first in case of locking issues
|
||||
foreach (string file in Directory.GetFiles(updatesFolderPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Deleted file: {file}");
|
||||
}
|
||||
catch (Exception fileEx)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Could not delete file {file}: {fileEx.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
// Then try to delete subdirectories
|
||||
foreach (string dir in Directory.GetDirectories(updatesFolderPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Deleted directory: {dir}");
|
||||
}
|
||||
catch (Exception dirEx)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Could not delete directory {dir}: {dirEx.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally try to delete the main directory
|
||||
try
|
||||
{
|
||||
Directory.Delete(updatesFolderPath, true);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Deleted updates folder: {updatesFolderPath}");
|
||||
}
|
||||
catch (Exception mainDirEx)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Could not completely delete updates folder: {mainDirEx.Message}", LogHelper.LogType.Warning);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Current version is up to date");
|
||||
return (null, bestGroup);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Updates folder does not exist: {updatesFolderPath}");
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 获取远程版本失败", LogHelper.LogType.Error);
|
||||
return (null, bestGroup);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error deleting updates folder: {ex.Message}", LogHelper.LogType.Error);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in CheckForUpdatesWithAutoLine: {ex.Message}", LogHelper.LogType.Error);
|
||||
return (null, null);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:版本修复方法,强制下载并安装指定通道的最新版本
|
||||
public static async Task<bool> FixVersion(UpdateChannel channel = UpdateChannel.Release)
|
||||
// 使用指定线路组下载新版
|
||||
public static async Task<bool> DownloadSetupFileWithLineGroup(string version, UpdateLineGroup group)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
|
||||
|
||||
// 获取远程版本号,而不是检查更新
|
||||
string remoteVersion = null;
|
||||
string proxy = null;
|
||||
|
||||
// 根据通道选择URL
|
||||
string primaryUrl, fallbackUrl;
|
||||
|
||||
if (channel == UpdateChannel.Release)
|
||||
{
|
||||
// Release通道版本信息地址
|
||||
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt";
|
||||
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beta通道版本信息地址
|
||||
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Retrieving remote version from {channel} channel");
|
||||
|
||||
// 先尝试主地址
|
||||
remoteVersion = await GetRemoteVersion(primaryUrl);
|
||||
|
||||
// 如果主地址失败,尝试备用地址
|
||||
if (remoteVersion == null)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed, trying fallback URL");
|
||||
remoteVersion = await GetRemoteVersion(fallbackUrl);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(remoteVersion))
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve remote version for fixing", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Remote version for fixing: {remoteVersion}");
|
||||
|
||||
// 无论版本是否为最新,都下载远程版本
|
||||
bool downloadResult = await DownloadSetupFileAndSaveStatus(remoteVersion, "", channel);
|
||||
|
||||
if (!downloadResult)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Failed to download update for fixing", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行安装,非静默模式
|
||||
InstallNewVersionApp(remoteVersion, false);
|
||||
|
||||
// 设置为用户主动退出,避免被看门狗判定为崩溃
|
||||
App.IsAppExitByUser = true;
|
||||
|
||||
// 关闭应用程序
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
|
||||
return true;
|
||||
string url = string.Format(group.DownloadUrlFormat, version);
|
||||
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Downloading from: {url}");
|
||||
return await DownloadFile(url, zipFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in FixVersion: {ex.Message}", LogHelper.LogType.Error);
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in DownloadSetupFileWithLineGroup: {ex.Message}", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取更新日志
|
||||
public static async Task<string> GetUpdateLog(UpdateChannel channel = UpdateChannel.Release)
|
||||
// 使用指定线路组获取更新日志
|
||||
public static async Task<string> GetUpdateLogWithLineGroup(UpdateLineGroup group)
|
||||
{
|
||||
try
|
||||
{
|
||||
string primaryUrl, fallbackUrl;
|
||||
|
||||
if (channel == UpdateChannel.Release)
|
||||
{
|
||||
// Release通道更新日志地址
|
||||
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/UpdateLog.md";
|
||||
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/UpdateLog.md";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beta通道更新日志地址
|
||||
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.md";
|
||||
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.md";
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Getting update log from {channel} channel");
|
||||
|
||||
// 先尝试主地址
|
||||
string updateLog = await GetRemoteContent(primaryUrl);
|
||||
|
||||
// 如果主地址失败,尝试备用地址
|
||||
if (string.IsNullOrEmpty(updateLog))
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed for update log, trying fallback URL");
|
||||
updateLog = await GetRemoteContent(fallbackUrl);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(updateLog))
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Successfully retrieved update log");
|
||||
return updateLog;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve update log from both URLs.", LogHelper.LogType.Error);
|
||||
return $"# 无法获取更新日志\n\n无法从服务器获取更新日志信息,请检查网络连接后重试。";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in GetUpdateLog: {ex.Message}", LogHelper.LogType.Error);
|
||||
return $"# 获取更新日志时发生错误\n\n错误信息: {ex.Message}";
|
||||
}
|
||||
return await AutoUpdateHelper.GetRemoteContent(group.LogUrl);
|
||||
}
|
||||
|
||||
// 获取远程内容的通用方法
|
||||
private static async Task<string> GetRemoteContent(string fileUrl)
|
||||
// 获取远程内容的通用方法(public 以便线路组方法调用)
|
||||
public static async Task<string> GetRemoteContent(string fileUrl)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
@@ -935,26 +740,18 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 设置超时时间为10秒
|
||||
client.Timeout = RequestTimeout;
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Sending HTTP request to: {fileUrl}");
|
||||
|
||||
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
|
||||
var downloadTask = client.GetAsync(fileUrl);
|
||||
var timeoutTask = Task.Delay(RequestTimeout);
|
||||
|
||||
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
|
||||
if (completedTask == timeoutTask)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {RequestTimeout.TotalSeconds} seconds", LogHelper.LogType.Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 请求完成,检查结果
|
||||
HttpResponseMessage response = await downloadTask;
|
||||
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | HTTP response status: {response.StatusCode}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
return content;
|
||||
}
|
||||
@@ -970,10 +767,75 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容旧接口:获取更新日志(自动选择最快线路组)
|
||||
public static async Task<string> GetUpdateLog(UpdateChannel channel = UpdateChannel.Release)
|
||||
{
|
||||
var group = await GetFastestLineGroup(channel);
|
||||
if (group == null) return "# 无法获取更新日志\n\n所有线路均不可用。";
|
||||
return await GetUpdateLogWithLineGroup(group);
|
||||
}
|
||||
|
||||
// 兼容旧接口:删除更新文件夹
|
||||
public static void DeleteUpdatesFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(updatesFolderPath))
|
||||
{
|
||||
// Try to delete all files first in case of locking issues
|
||||
foreach (string file in Directory.GetFiles(updatesFolderPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
try { File.Delete(file); } catch { }
|
||||
}
|
||||
foreach (string dir in Directory.GetDirectories(updatesFolderPath))
|
||||
{
|
||||
try { Directory.Delete(dir, true); } catch { }
|
||||
}
|
||||
try { Directory.Delete(updatesFolderPath, true); } catch { }
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
// 兼容旧接口:版本修复方法,强制下载并安装指定通道的最新版本
|
||||
public static async Task<bool> FixVersion(UpdateChannel channel = UpdateChannel.Release)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
|
||||
// 获取远程版本号(自动选择最快线路组,始终下载远程版本)
|
||||
var (remoteVersion, group) = await CheckForUpdatesWithAutoLine(channel, true);
|
||||
if (string.IsNullOrEmpty(remoteVersion) || group == null)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve remote version for fixing", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Remote version for fixing: {remoteVersion}");
|
||||
// 无论版本是否为最新,都下载远程版本
|
||||
bool downloadResult = await DownloadSetupFileWithLineGroup(remoteVersion, group);
|
||||
if (!downloadResult)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Failed to download update for fixing", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
// 执行安装,非静默模式
|
||||
InstallNewVersionApp(remoteVersion, false);
|
||||
App.IsAppExitByUser = true;
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in FixVersion: {ex.Message}", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AutoUpdateWithSilenceTimeComboBox
|
||||
|
||||
@@ -499,12 +499,16 @@ namespace Ink_Canvas {
|
||||
if (RadioCrashSilentRestart != null && RadioCrashSilentRestart.IsChecked == true)
|
||||
{
|
||||
App.CrashAction = App.CrashActionType.SilentRestart;
|
||||
Settings.Startup.CrashAction = 0;
|
||||
}
|
||||
else if (RadioCrashNoAction != null && RadioCrashNoAction.IsChecked == true)
|
||||
{
|
||||
App.CrashAction = App.CrashActionType.NoAction;
|
||||
Settings.Startup.CrashAction = 1;
|
||||
}
|
||||
SaveSettingsToFile();
|
||||
// 强制同步全局变量,防止后台逻辑未及时感知
|
||||
App.SyncCrashActionFromSettings();
|
||||
}
|
||||
|
||||
// 添加一个辅助方法,根据当前编辑模式设置光标
|
||||
|
||||
@@ -20,40 +20,45 @@ namespace Ink_Canvas {
|
||||
SaveInkCanvasStrokes(true, true);
|
||||
}
|
||||
|
||||
private void SaveInkCanvasStrokes(Boolean newNotice, Boolean saveByUser) {
|
||||
private void SaveInkCanvasStrokes(Boolean newNotice, Boolean saveByUser, string userSavePath = null) {
|
||||
try {
|
||||
// 修改保存路径为软件根目录下的Saves文件夹
|
||||
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (string.IsNullOrEmpty(appDirectory))
|
||||
{
|
||||
appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
}
|
||||
|
||||
string savePath = Path.Combine(appDirectory, "Saves",
|
||||
(saveByUser ? @"User Saved - " : @"Auto Saved - ") +
|
||||
(currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes"));
|
||||
|
||||
if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
|
||||
// 优先使用用户指定的保存路径,否则使用默认路径
|
||||
string savePathWithName;
|
||||
if (currentMode != 0) // 黑板模式下
|
||||
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + " Page-" +
|
||||
CurrentWhiteboardIndex + " StrokesCount-" + inkCanvas.Strokes.Count + ".icstk";
|
||||
else
|
||||
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk";
|
||||
if (!string.IsNullOrEmpty(userSavePath)) {
|
||||
// 用户指定了完整保存路径(含文件名)
|
||||
savePathWithName = userSavePath;
|
||||
string dir = Path.GetDirectoryName(savePathWithName);
|
||||
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||||
} else {
|
||||
// 默认保存到软件根目录下的Saves文件夹
|
||||
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (string.IsNullOrEmpty(appDirectory))
|
||||
appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
string savePath = Path.Combine(appDirectory, "Saves",
|
||||
(saveByUser ? @"User Saved - " : @"Auto Saved - ") +
|
||||
(currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes"));
|
||||
if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
|
||||
if (currentMode != 0) // 黑板模式下
|
||||
savePathWithName = Path.Combine(savePath, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") +
|
||||
" Page-" + CurrentWhiteboardIndex + " StrokesCount-" + inkCanvas.Strokes.Count + ".icstk");
|
||||
else
|
||||
savePathWithName = Path.Combine(savePath, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk");
|
||||
}
|
||||
|
||||
try {
|
||||
using (FileStream fs = new FileStream(savePathWithName, FileMode.Create)) {
|
||||
using (FileStream fs = new FileStream(savePathWithName, FileMode.Create)) {
|
||||
inkCanvas.Strokes.Save(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (ex is UnauthorizedAccessException || ex is DirectoryNotFoundException) {
|
||||
// 修改异常处理中的备用路径为软件根目录下的Saves文件夹
|
||||
// 异常时备用路径仍为默认Saves文件夹
|
||||
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (string.IsNullOrEmpty(appDirectory))
|
||||
appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
string fallbackPath = Path.Combine(appDirectory, "Saves");
|
||||
Directory.CreateDirectory(fallbackPath);
|
||||
|
||||
string fileName = Path.GetFileNameWithoutExtension(savePathWithName) + "_retry.icstk";
|
||||
string newPath = Path.Combine(fallbackPath, fileName);
|
||||
|
||||
try {
|
||||
using (FileStream fs = new FileStream(newPath, FileMode.Create)) {
|
||||
inkCanvas.Strokes.Save(fs);
|
||||
|
||||
@@ -115,6 +115,22 @@ namespace Ink_Canvas {
|
||||
Settings.Startup = new Startup();
|
||||
}
|
||||
|
||||
// 恢复崩溃后操作设置
|
||||
if (Settings.Startup != null)
|
||||
{
|
||||
// 恢复崩溃后操作选项
|
||||
if (Settings.Startup.CrashAction == 0)
|
||||
{
|
||||
App.CrashAction = App.CrashActionType.SilentRestart;
|
||||
if (RadioCrashSilentRestart != null) RadioCrashSilentRestart.IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.CrashAction = App.CrashActionType.NoAction;
|
||||
if (RadioCrashNoAction != null) RadioCrashNoAction.IsChecked = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Appearance
|
||||
if (Settings.Appearance != null) {
|
||||
if (!Settings.Appearance.IsEnableDisPlayNibModeToggler) {
|
||||
|
||||
@@ -40,9 +40,10 @@ namespace Ink_Canvas {
|
||||
}
|
||||
|
||||
private void MainWindow_TouchDown(object sender, TouchEventArgs e) {
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint
|
||||
|| inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke
|
||||
|| inkCanvas.EditingMode == InkCanvasEditingMode.Select) return;
|
||||
// 允许触摸在擦除、套索等模式下也能操作,不再直接 return
|
||||
// if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint
|
||||
// || inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke
|
||||
// || inkCanvas.EditingMode == InkCanvasEditingMode.Select) return;
|
||||
|
||||
if (!isHidingSubPanelsWhenInking) {
|
||||
isHidingSubPanelsWhenInking = true;
|
||||
@@ -71,7 +72,6 @@ namespace Ink_Canvas {
|
||||
}
|
||||
|
||||
private void MainWindow_StylusDown(object sender, StylusDownEventArgs e) {
|
||||
|
||||
inkCanvas.CaptureStylus();
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
@@ -94,9 +94,9 @@ namespace Ink_Canvas {
|
||||
System.Windows.Forms.Cursor.Show();
|
||||
}
|
||||
|
||||
// 只在橡皮和线擦时 return,套索选区不 return
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint
|
||||
|| inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke
|
||||
|| inkCanvas.EditingMode == InkCanvasEditingMode.Select) return;
|
||||
|| inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke)
|
||||
|
||||
TouchDownPointsList[e.StylusDevice.Id] = InkCanvasEditingMode.None;
|
||||
}
|
||||
@@ -305,6 +305,9 @@ namespace Ink_Canvas {
|
||||
private InkCanvasEditingMode lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
|
||||
private bool isSingleFingerDragMode = false;
|
||||
|
||||
// 记录手掌擦前的编辑模式
|
||||
private InkCanvasEditingMode prevEditingModeBeforePalmEraser = InkCanvasEditingMode.Ink;
|
||||
|
||||
private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e) {
|
||||
|
||||
inkCanvas.CaptureTouch(e.TouchDevice);
|
||||
@@ -312,7 +315,7 @@ namespace Ink_Canvas {
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
|
||||
dec.Add(e.TouchDevice.Id);
|
||||
//设备1个的时候,记录中心点
|
||||
// 设备1个的时候,记录中心点
|
||||
if (dec.Count == 1) {
|
||||
var touchPoint = e.GetTouchPoint(inkCanvas);
|
||||
centerPoint = touchPoint.Position;
|
||||
@@ -320,13 +323,31 @@ namespace Ink_Canvas {
|
||||
//记录第一根手指点击时的 StrokeCollection
|
||||
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
|
||||
}
|
||||
//设备两个及两个以上,将画笔功能关闭
|
||||
if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) {
|
||||
if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return;
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.None ||
|
||||
inkCanvas.EditingMode == InkCanvasEditingMode.Select) return;
|
||||
lastInkCanvasEditingMode = inkCanvas.EditingMode;
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
||||
|
||||
// 多指书写功能开启时禁用手掌擦
|
||||
if (Settings.Gesture.IsEnableTwoFingerGesture) {
|
||||
// 关闭手掌擦逻辑
|
||||
if (dec.Count > 1) {
|
||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.None && inkCanvas.EditingMode != InkCanvasEditingMode.Select) {
|
||||
lastInkCanvasEditingMode = inkCanvas.EditingMode;
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 3指及以上触控时触发手掌擦
|
||||
if (dec.Count >= 3) {
|
||||
// 记录触发前的模式
|
||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) {
|
||||
prevEditingModeBeforePalmEraser = inkCanvas.EditingMode;
|
||||
}
|
||||
// 切换为橡皮
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
|
||||
isLastTouchEraser = true;
|
||||
// 可自定义橡皮形状
|
||||
currentPalmEraserShape = GetPalmRectangleEraserShape();
|
||||
inkCanvas.EraserShape = currentPalmEraserShape;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,30 +356,23 @@ namespace Ink_Canvas {
|
||||
ViewboxFloatingBar.IsHitTestVisible = true;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
||||
|
||||
//手势完成后切回之前的状态
|
||||
if (dec.Count > 1)
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.None)
|
||||
inkCanvas.EditingMode = lastInkCanvasEditingMode;
|
||||
dec.Remove(e.TouchDevice.Id);
|
||||
inkCanvas.Opacity = 1;
|
||||
|
||||
// 如果是手掌触发的面积擦抬起,需要确保橡皮擦形状被正确重置
|
||||
if (isLastTouchEraser && dec.Count == 0) {
|
||||
isLastTouchEraser = false;
|
||||
currentPalmEraserShape = null; // 清除保存的手掌擦形状
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && forcePointEraser) {
|
||||
// 重新应用当前设置的橡皮擦形状
|
||||
ApplyCurrentEraserShape();
|
||||
|
||||
// 没有触控输入后,自动恢复手掌擦前的功能
|
||||
if (dec.Count == 0) {
|
||||
if (isLastTouchEraser) {
|
||||
isLastTouchEraser = false;
|
||||
currentPalmEraserShape = null;
|
||||
inkCanvas.EditingMode = prevEditingModeBeforePalmEraser;
|
||||
}
|
||||
}
|
||||
|
||||
if (dec.Count == 0)
|
||||
if (lastTouchDownStrokeCollection.Count() != inkCanvas.Strokes.Count() &&
|
||||
!(drawingShapeMode == 9 && !isFirstTouchCuboid)) {
|
||||
var whiteboardIndex = CurrentWhiteboardIndex;
|
||||
if (currentMode == 0) whiteboardIndex = 0;
|
||||
strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void inkCanvas_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
|
||||
|
||||
@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.0.3")]
|
||||
[assembly: AssemblyFileVersion("1.7.0.3")]
|
||||
[assembly: AssemblyVersion("1.7.0.4")]
|
||||
[assembly: AssemblyFileVersion("1.7.0.4")]
|
||||
|
||||
@@ -116,19 +116,14 @@ namespace Ink_Canvas
|
||||
public string AutoUpdateWithSilenceEndTime { get; set; } = "22:00";
|
||||
[JsonProperty("updateChannel")]
|
||||
public UpdateChannel UpdateChannel { get; set; } = UpdateChannel.Release;
|
||||
|
||||
[JsonProperty("skippedVersion")]
|
||||
public string SkippedVersion { get; set; } = "";
|
||||
|
||||
[JsonProperty("isEnableNibMode")]
|
||||
public bool IsEnableNibMode { get; set; } = false;
|
||||
/*
|
||||
[JsonProperty("isAutoHideCanvas")]
|
||||
public bool IsAutoHideCanvas { get; set; } = true;
|
||||
[JsonProperty("isAutoEnterModeFinger")]
|
||||
public bool IsAutoEnterModeFinger { get; set; } = false;*/
|
||||
[JsonProperty("isFoldAtStartup")]
|
||||
public bool IsFoldAtStartup { get; set; } = false;
|
||||
[JsonProperty("crashAction")]
|
||||
public int CrashAction { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class Appearance
|
||||
|
||||
Reference in New Issue
Block a user