diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2e973aa..d60d726 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -161,18 +161,13 @@ jobs:
schtasks /Delete /TN "ThreadPilot_Startup" /F >nul 2>&1
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "ThreadPilot" /f >nul 2>&1
- echo [3/4] Optional user data cleanup...
- set "REMOVE_DATA=N"
- set /p REMOVE_DATA=Do you want to remove user settings at "%APPDATA%\ThreadPilot"? [y/N]:
- if /I "%REMOVE_DATA%"=="Y" (
- if exist "%APPDATA%\ThreadPilot" (
- rd /s /q "%APPDATA%\ThreadPilot"
- echo User settings removed.
- ) else (
- echo No user settings folder found.
- )
+ echo [3/4] Removing ThreadPilot user data for this Windows account...
+ rem Full uninstall removes only ThreadPilot-owned per-user AppData. Normal install/update paths never run this script.
+ if exist "%APPDATA%\ThreadPilot" (
+ rd /s /q "%APPDATA%\ThreadPilot"
+ echo ThreadPilot user data removed.
) else (
- echo User settings were kept.
+ echo No ThreadPilot user data folder found.
)
echo [4/4] Scheduling app folder removal...
diff --git a/App.xaml b/App.xaml
index 592dae1..58f3c0d 100644
--- a/App.xaml
+++ b/App.xaml
@@ -10,6 +10,7 @@
+
diff --git a/App.xaml.cs b/App.xaml.cs
index 9aa438f..06dc022 100644
--- a/App.xaml.cs
+++ b/App.xaml.cs
@@ -63,50 +63,22 @@ public App()
protected override void OnStartup(StartupEventArgs e)
{
// Parse command line arguments early so special startup modes can short-circuit normal flow.
- bool startMinimized = false;
- bool isAutostart = false;
- bool isSmokeTest = false;
- bool registerLaunchTask = false;
- bool launchedViaTask = false;
-#if DEBUG
- bool isTestMode = false;
-#endif
+ var startupMode = StartupMode.Parse(e.Args);
bool effectiveStartMinimized = false;
ApplicationSettingsModel? loadedSettings = null;
- foreach (var arg in e.Args)
+ effectiveStartMinimized = startupMode.StartMinimized;
+
+ if (startupMode.IsSmokeTest)
{
- switch (arg.ToLowerInvariant())
- {
-#if DEBUG
- case "--test":
- isTestMode = true;
- break;
-#endif
- case "--smoke-test":
- isSmokeTest = true;
- break;
- case "--start-minimized":
- startMinimized = true;
- break;
- case "--autostart":
- isAutostart = true;
- break;
- case "--startup": // Alternative startup argument
- isAutostart = true;
- startMinimized = true;
- break;
- case RegisterLaunchTaskArgument:
- registerLaunchTask = true;
- break;
- case LaunchedViaTaskArgument:
- launchedViaTask = true;
- break;
- }
+ var smokeLogger = this.ServiceProvider.GetRequiredService>();
+ var smokeTestResult = this.RunSmokeTestWithTimeout(smokeLogger, TimeSpan.FromSeconds(10));
+ Environment.ExitCode = smokeTestResult;
+ this.Shutdown(smokeTestResult);
+ Environment.Exit(smokeTestResult);
+ return;
}
- effectiveStartMinimized = startMinimized;
-
// Set up global exception handlers first
AppDomain.CurrentDomain.UnhandledException += this.OnUnhandledException;
this.DispatcherUnhandledException += this.OnDispatcherUnhandledException;
@@ -130,14 +102,14 @@ protected override void OnStartup(StartupEventArgs e)
}
else
{
- if (launchedViaTask)
+ if (startupMode.LaunchedViaTask)
{
logger.LogError("Application was launched via managed task marker but is still not elevated.");
}
#if DEBUG
- else if (!isSmokeTest && !isTestMode)
+ else if (!startupMode.IsTestMode)
#else
- else if (!isSmokeTest)
+ else
#endif
{
var launchedElevatedInstance = Task.Run(async () => await elevatedTaskService.TryRunLaunchTaskAsync()).GetAwaiter().GetResult();
@@ -148,7 +120,7 @@ protected override void OnStartup(StartupEventArgs e)
return;
}
- if (!registerLaunchTask)
+ if (!startupMode.RegisterLaunchTask)
{
logger.LogInformation("Managed elevated launch task is unavailable. Requesting one-time elevation to bootstrap persistent launch.");
var restartInitiated = Task.Run(async () => await elevationService.RestartWithElevation(new[] { RegisterLaunchTaskArgument })).GetAwaiter().GetResult();
@@ -160,9 +132,9 @@ protected override void OnStartup(StartupEventArgs e)
}
#if DEBUG
- if (!isSmokeTest && !isTestMode)
+ if (!startupMode.IsTestMode)
#else
- if (!isSmokeTest)
+ if (true)
#endif
{
logger.LogError("ThreadPilot requires administrator privileges and cannot continue without elevation.");
@@ -170,33 +142,28 @@ protected override void OnStartup(StartupEventArgs e)
this.Shutdown(1);
return;
}
-
- logger.LogWarning("Application is running without administrator privileges in smoke test mode.");
}
// Enforce single-instance after elevation bootstrap logic to avoid mutex races during handoff.
- if (!isSmokeTest)
+ bool createdNew;
+ this.singleInstanceMutex = new Mutex(initiallyOwned: true, name: "Global\\ThreadPilot_SingleInstance", createdNew: out createdNew);
+ if (!createdNew)
{
- bool createdNew;
- this.singleInstanceMutex = new Mutex(initiallyOwned: true, name: "Global\\ThreadPilot_SingleInstance", createdNew: out createdNew);
- if (!createdNew)
- {
- System.Windows.MessageBox.Show(
- "ThreadPilot is already running.",
- "Instance already open",
- MessageBoxButton.OK,
- MessageBoxImage.Information);
+ System.Windows.MessageBox.Show(
+ "ThreadPilot is already running.",
+ "Instance already open",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
- this.Shutdown();
- return;
- }
+ this.Shutdown();
+ return;
}
base.OnStartup(e);
// Check for test mode
#if DEBUG
- if (isTestMode)
+ if (startupMode.IsTestMode)
{
// Run in console test mode
AllocConsole();
@@ -209,22 +176,17 @@ protected override void OnStartup(StartupEventArgs e)
}
#endif
- if (isSmokeTest)
- {
- var smokeTestResult = Task.Run(async () => await this.RunSmokeTestAsync(logger)).GetAwaiter().GetResult();
- this.Shutdown(smokeTestResult);
- return;
- }
-
try
{
var settingsService = this.ServiceProvider.GetRequiredService();
var themeService = this.ServiceProvider.GetRequiredService();
+ var localizationService = this.ServiceProvider.GetRequiredService();
Task.Run(async () => await settingsService.LoadSettingsAsync()).GetAwaiter().GetResult();
var settings = settingsService.Settings;
loadedSettings = settings;
- effectiveStartMinimized = startMinimized || settings.StartMinimized;
+ localizationService.ApplyLanguage(settings.Language);
+ effectiveStartMinimized = startupMode.StartMinimized || settings.StartMinimized;
var useDarkTheme = settings.HasUserThemePreference
? settings.UseDarkTheme
: themeService.GetSystemUsesDarkTheme();
@@ -256,7 +218,7 @@ protected override void OnStartup(StartupEventArgs e)
throw new InvalidOperationException("MainWindow could not be created");
}
- var startupWindowBehavior = StartupWindowBehavior.Resolve(isAutostart, effectiveStartMinimized);
+ var startupWindowBehavior = StartupWindowBehavior.Resolve(startupMode.IsAutostart, effectiveStartMinimized);
var showStartupSuggestion = loadedSettings != null
&& StartupMinimizedSuggestionPolicy.ShouldShow(loadedSettings, startupWindowBehavior);
mainWindow.ConfigureStartupMode(
@@ -299,16 +261,33 @@ protected override void OnStartup(StartupEventArgs e)
}
}
- private async Task RunSmokeTestAsync(ILogger logger)
+ private int RunSmokeTestWithTimeout(ILogger logger, TimeSpan timeout)
+ {
+ var smokeTestTask = Task.Run(() => this.RunSmokeTest(logger));
+ if (smokeTestTask.Wait(timeout))
+ {
+ return smokeTestTask.GetAwaiter().GetResult();
+ }
+
+ logger.LogError("ThreadPilot smoke test timed out after {TimeoutSeconds} seconds", timeout.TotalSeconds);
+ return 2;
+ }
+
+ private int RunSmokeTest(ILogger logger)
{
try
{
logger.LogInformation("Starting ThreadPilot smoke test");
- var settingsService = this.ServiceProvider.GetRequiredService();
- await settingsService.LoadSettingsAsync().ConfigureAwait(false);
- _ = this.ServiceProvider.GetRequiredService();
- _ = this.ServiceProvider.GetRequiredService();
+ _ = this.ServiceProvider.GetRequiredService();
+ _ = this.ServiceProvider.GetRequiredService();
+ _ = this.ServiceProvider.GetRequiredService();
+ _ = this.ServiceProvider.GetRequiredService();
+
+ if (!System.IO.Directory.Exists(AppContext.BaseDirectory))
+ {
+ throw new InvalidOperationException("Application base directory was not found.");
+ }
logger.LogInformation("ThreadPilot smoke test completed successfully");
return 0;
@@ -320,6 +299,55 @@ private async Task RunSmokeTestAsync(ILogger logger)
}
}
+ private readonly struct StartupMode
+ {
+ public bool StartMinimized { get; init; }
+
+ public bool IsAutostart { get; init; }
+
+ public bool IsSmokeTest { get; init; }
+
+ public bool RegisterLaunchTask { get; init; }
+
+ public bool LaunchedViaTask { get; init; }
+
+ public bool IsTestMode { get; init; }
+
+ public static StartupMode Parse(IEnumerable args)
+ {
+ var mode = default(StartupMode);
+ foreach (var arg in args)
+ {
+ switch (arg.ToLowerInvariant())
+ {
+ case "--test":
+ mode = mode with { IsTestMode = true };
+ break;
+ case "--smoke-test":
+ mode = mode with { IsSmokeTest = true };
+ break;
+ case "--start-minimized":
+ mode = mode with { StartMinimized = true };
+ break;
+ case "--autostart":
+ mode = mode with { IsAutostart = true };
+ break;
+ case "--startup":
+ mode = mode with { IsAutostart = true, StartMinimized = true };
+ break;
+ case RegisterLaunchTaskArgument:
+ mode = mode with { RegisterLaunchTask = true };
+ break;
+ case LaunchedViaTaskArgument:
+ mode = mode with { LaunchedViaTask = true };
+ break;
+ }
+ }
+
+ return mode;
+ }
+ }
+
protected override void OnExit(ExitEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException -= this.OnUnhandledException;
diff --git a/Installer/Installer.iss b/Installer/Installer.iss
index 8beead0..a17973c 100644
--- a/Installer/Installer.iss
+++ b/Installer/Installer.iss
@@ -5,7 +5,7 @@
#define MyAppPublisher "ThreadPilot"
#define MyAppURL "https://github.com/"
#define MyAppExeName "ThreadPilot.exe"
-#define MyAppVersion "1.2.0"
+#define MyAppVersion "1.4.0"
#ifndef MyWizardStyle
#define MyWizardStyle "modern dynamic windows11"
@@ -20,7 +20,7 @@
AppId={{A2A4C8B5-4A9A-4B1B-93F4-5F8B1C7E8C2A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
-AppVerName={#MyAppName} {#MyAppVersion}
+AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
@@ -54,7 +54,15 @@ Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: de
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
[UninstallRun]
-Filename: taskkill.exe; Parameters: "/IM '{#MyAppExeName}' /F"; Flags: runhidden waituntilterminated; RunOnceId: UninstallKill
+Filename: "taskkill.exe"; Parameters: "/IM ""{#MyAppExeName}"" /F"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallKill"
+Filename: "schtasks.exe"; Parameters: "/Delete /TN ""ThreadPilot_Startup"" /F"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallRemoveThreadPilotStartupTask"
+Filename: "reg.exe"; Parameters: "delete ""HKCU\Software\Microsoft\Windows\CurrentVersion\Run"" /v ""ThreadPilot"" /f"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallRemoveThreadPilotRunEntry"
+
+; ThreadPilot user data is preserved during install/update and removed only when
+; the generated uninstaller runs. Per-user AppData cleanup is limited to the
+; account context used by uninstall.
+[UninstallDelete]
+Type: filesandordirs; Name: "{userappdata}\ThreadPilot"
[Code]
diff --git a/Installer/ThreadPilot.wxs b/Installer/ThreadPilot.wxs
index c924f7c..8bcf6f1 100644
--- a/Installer/ThreadPilot.wxs
+++ b/Installer/ThreadPilot.wxs
@@ -7,7 +7,7 @@
diff --git a/Installer/setup.iss b/Installer/setup.iss
index 9cfc206..7fbed61 100644
--- a/Installer/setup.iss
+++ b/Installer/setup.iss
@@ -11,7 +11,7 @@
#endif
#ifndef MyAppVersion
- #define MyAppVersion "1.2.0"
+ #define MyAppVersion "1.4.0"
#endif
#ifndef MyAppSourceDir
@@ -22,7 +22,7 @@
AppId={{E8F7A3B2-5C4D-4E6F-8A9B-1C2D3E4F5A6B}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
-AppVerName={#MyAppName} {#MyAppVersion}
+AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}/issues
@@ -62,3 +62,49 @@ Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
; Intentionally do not auto-launch after setup to keep package-manager installs unattended.
+; ThreadPilot user data is preserved during install/update. Inno removes installed
+; files and shortcuts automatically only when the generated uninstaller runs.
+; Per-user AppData cleanup is limited to the account context used by uninstall.
+[UninstallRun]
+Filename: "taskkill.exe"; Parameters: "/IM ""{#MyAppExeName}"" /F"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallKillThreadPilot"
+Filename: "schtasks.exe"; Parameters: "/Delete /TN ""ThreadPilot_Startup"" /F"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallRemoveThreadPilotStartupTask"
+Filename: "reg.exe"; Parameters: "delete ""HKCU\Software\Microsoft\Windows\CurrentVersion\Run"" /v ""ThreadPilot"" /f"; Flags: runhidden waituntilterminated; RunOnceId: "UninstallRemoveThreadPilotRunEntry"
+
+[UninstallDelete]
+Type: filesandordirs; Name: "{userappdata}\ThreadPilot"
+
+[Code]
+const
+ LegacyBetaUninstallKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{A2A4C8B5-4A9A-4B1B-93F4-5F8B1C7E8C2A}_is1';
+ LegacyBetaDisplayName = 'ThreadPilot 0.1.0-beta';
+
+function IsLegacyThreadPilotInstallPath(InstallLocation: string): Boolean;
+var
+ NormalizedLocation: string;
+ ExpectedInstallRoot: string;
+begin
+ NormalizedLocation := Lowercase(RemoveBackslashUnlessRoot(RemoveQuotes(InstallLocation)));
+ ExpectedInstallRoot := Lowercase(RemoveBackslashUnlessRoot(ExpandConstant('{autopf}\ThreadPilot')));
+ Result := (NormalizedLocation = ExpectedInstallRoot);
+end;
+
+procedure DeleteLegacyBetaUninstallEntry(RootKey: Integer);
+var
+ DisplayName: string;
+ InstallLocation: string;
+begin
+ if RegQueryStringValue(RootKey, LegacyBetaUninstallKey, 'DisplayName', DisplayName) and
+ RegQueryStringValue(RootKey, LegacyBetaUninstallKey, 'InstallLocation', InstallLocation) and
+ (DisplayName = LegacyBetaDisplayName) and
+ IsLegacyThreadPilotInstallPath(InstallLocation) then
+ begin
+ RegDeleteKeyIncludingSubkeys(RootKey, LegacyBetaUninstallKey);
+ end;
+end;
+
+function InitializeSetup(): Boolean;
+begin
+ DeleteLegacyBetaUninstallEntry(HKLM);
+ DeleteLegacyBetaUninstallEntry(HKCU);
+ Result := True;
+end;
diff --git a/Locales/en-US.xaml b/Locales/en-US.xaml
new file mode 100644
index 0000000..e2bc6fd
--- /dev/null
+++ b/Locales/en-US.xaml
@@ -0,0 +1,655 @@
+
+
+
+ ThreadPilot - Process & Power Plan Manager
+ Administrator Privileges Recommended
+ ThreadPilot is running with limited privileges. Some features may not be available.
+ Administrator access is required for:
+ • Modifying power plan configurations
+ • Changing process CPU affinity and priority
+ • Applying system-level optimizations and tweaks
+ • Managing protected processes
+ Continue Without Elevation
+ Request Elevation
+
+
+ Process Management
+ CPU Masks
+ Power Plans
+ Rules
+ Diagnostics
+ ThreadPilot Activity
+ Tweaks
+ Settings
+
+
+ Startup minimized
+ Enable Startup minimized when you want ThreadPilot to start silently in the tray on future Windows sign-ins.
+ Recommended
+ Don't show again
+ Open Settings
+ Primary navigation
+ Elevation warning overlay
+ Performance introduction overlay
+ Startup minimized suggestion
+ Unsaved settings dialog
+ Application startup loading overlay
+
+
+ ThreadPilot Activity
+ Shows actions performed by ThreadPilot, including applied rules, affinity changes, priority changes, power plan changes, settings changes, tweaks, optimizations, and safe failure messages.
+ Search:
+ Category:
+ Level:
+ From:
+ To:
+ Refresh
+ Clear Display
+ Export Activity
+ Cleanup Diagnostic Files
+ Open Diagnostic Folder
+
+
+ Time
+ Status
+ Category
+ Message
+ Details
+ ID
+ Copy Entry
+ Refresh
+ No log entries to display
+ Adjust filters or refresh logs to load recent ThreadPilot activity.
+
+
+ Activity Details
+ Timestamp:
+ Status:
+ Category:
+ Message:
+ Details:
+ Correlation ID:
+ No log entry selected
+ Files:
+ Size:
+ Debug Diagnostics
+ Max Size (MB):
+ Retention (Days):
+ Save Settings
+
+
+ CPU Masks
+ Create reusable CPU affinity presets for per-process use.
+ Selecting a mask here only edits the preset. It does not change CPU affinity until you apply it to a process or save it in a process rule.
+ New
+ Delete
+ Duplicate Mask
+ Mask Information
+ Name:
+ Description:
+ Enabled
+ Default preset
+ Pre-selected when ThreadPilot needs a fallback mask or when creating per-process rules. It does not apply CPU affinity automatically.
+ Disable to temporarily hide this mask
+ Select CPUs
+ Toggle CPUs to edit this mask preset. Changes are saved automatically and do not affect running processes. All Cores is the protected default preset.
+ Mask names, descriptions, CPU selections, and options are saved automatically.
+ Create a new CPU mask
+ Delete selected mask
+ CPUs
+ CPU
+ Mask Options
+
+
+ Optional Diagnostics
+ Diagnostics are optional and intended for troubleshooting. For in-game overlays and detailed performance graphs, use dedicated tools.
+ Diagnostics are optional and intended for troubleshooting.
+ For in-game overlays and detailed performance graphs, use dedicated tools.
+ Quick tips:
+ 1. Open diagnostics only when you need a focused troubleshooting snapshot.
+ 2. Review hotspots only as a hint before creating automation rules.
+ 3. Stop live metrics when you are done troubleshooting.
+ Continue to Diagnostics
+
+ Active Processes
+ Top CPU and memory consumers with one-click rule creation.
+ Search processes by name
+ Rule-backed only
+ Actionable only
+ Rule Impact
+ Create/Update Rule from Selection
+ Create or update an automation rule from the selected hotspot process
+
+ Stability Timeline
+ Clear History
+ Clear the displayed metrics and timeline history
+ Core Snapshot
+ Per-core utilization for quick imbalance checks.
+ Toggle Core Panel
+ Toggle Process Panel
+ Start Live Metrics
+ Start live metrics collection for this dashboard
+ Stop Live Metrics
+ Pause live metrics collection; background automation is separate
+ Refresh
+ Refresh the current dashboard snapshot
+
+ Global Power Plan
+ Process Hotspots
+ Filter
+ Memory
+ Name
+ Priority
+ Window
+ Memory Used
+ CPU %
+ Mem %
+ Threads
+ Events
+ Severity
+ Detail
+ Time
+ Category
+ Process
+ Selected hotspot process
+ Metrics
+ Processes
+
+
+ Power Plans
+ Manage the active Windows power plan and import custom .pow profiles
+ Windows Power Plans
+ Select the Windows plan to make active.
+ Set as Active Windows Plan
+ Change the active Windows power plan to the selected plan
+ Refresh Plans
+ Refresh the list of available power plans
+ Custom Power Plans
+ Local .pow files ready to import into Windows.
+ Import Selected .pow
+ Import the selected custom .pow file into Windows
+ Add .pow File
+ Add a new custom power plan file to the custom library
+ Delete
+ Active
+
+
+ Rules & Automation
+ Automation monitoring watches process start/stop events and applies configured power plan, CPU mask, and priority rules.
+ Rule Editor
+ Create a rule from an executable or running process to automate power plan, CPU mask, and priority behavior.
+ Executable Match:
+ Match by Path
+ Match processes by full path instead of just executable name
+ Browse for Executable
+ Click to select an executable file (.exe) from your computer
+ Choose an executable. Match by path is more precise; matching by name applies to any process with that executable name.
+ Use Running Process:
+ Select a currently running process to use its executable
+ Use Selected Process
+ Use the executable from the selected running process
+ Rule Power Plan (global switch):
+ When this rule matches, Windows switches the global active power plan.
+ Rule CPU Mask:
+ Optional: Select a CPU mask to apply when this process starts
+ Rule Priority
+ Update
+ Optional: Select the process priority to apply when this process starts
+ Association Priority:
+ Higher priority associations take precedence when multiple match
+ Add Rule
+ Update Selected Rule
+ Update the selected association
+ Clear Selection
+ Clear the selected executable
+
+ Current Rules
+ Define per-process rules. Power plans are global; masks and priorities apply to matching processes.
+ Remove
+ Remove the selected association
+ Default Power Plan (fallback when no rule matches)
+ Power plan to use when no associated processes are running:
+ Set Default Power Plan
+
+ Automation Monitoring Settings
+ Enable Event-Based Automation (WMI)
+ Enable Automation Fallback Polling
+ Polling Interval (seconds):
+ Power Plan Change Delay (ms):
+ Prevent Duplicate Power Plan Changes
+ Save Configuration
+ No automation rules yet
+ Status:
+ Automation Monitoring
+ Start Automation Monitoring
+ Stop Automation Monitoring
+
+ Applied to each matching process when the automation rule runs.
+ Applied only to matching processes; it does not change the global Windows power plan.
+ Selected Executable:
+ Description:
+ Automation Service
+ Rules
+ Executable
+ Power Plan
+ CPU Mask
+ Priority
+ Description
+ Process Priority:
+
+
+ Process Management
+ Search, filter, and control active process configurations
+ Search processes by name
+ Process search
+ Hide Windows system processes
+ Hide System Processes
+ Hide processes with very low CPU usage
+ Hide Idle Processes
+ Show only applications with visible windows
+ Active Apps Only
+ Lock process list
+ Pause process list refresh and sorting updates while you work with the current list. Background monitoring and saved-rule auto-apply continue while ThreadPilot is running.
+ Sort by:
+ Choose how to sort the process list
+
+ Selected Process
+ No process selected
+ Select a process from the table to enable affinity, priority, power plan, and rule actions.
+ Power Plan / Pending Settings
+ Choose the power plan to activate manually or include with quick apply
+ Set Power Plan
+ Activate the selected Windows power plan
+
+ Pending core mask
+ Select a mask to stage it. This does not change OS affinity until Apply Affinity is clicked.
+ Apply Affinity
+ Apply the pending core mask to the selected process and verify the Windows affinity state
+ Apply Affinity and Save as Rule
+ Save current process settings as a rule. These settings will be automatically applied when this process starts in the future.
+
+ Set CPU Priority
+ Apply the selected priority to the process
+ Enforce Priority by Registry
+ Apply priority through Windows registry. Process must be restarted for changes to take effect. This setting persists across system reboots.
+ Set Priority
+ Realtime priority is blocked by ThreadPilot because it can make Windows unstable or unresponsive.
+ Realtime (blocked)
+
+ Disable Idle Server
+ Prevents the system from entering idle state while this process is running. Useful for games and performance-critical applications.
+
+ Profile / Rule
+ Enter a profile name to save or load settings
+ Save Profile
+ Save current CPU affinity and priority as a reusable profile
+ Load Profile
+ Load a previously saved profile
+ Save Current Settings as Rule
+
+ Last ThreadPilot action:
+ Refresh
+ Refresh the process list
+ Load More
+ Load more processes
+ Refresh processes
+ Load more processes
+ Running process list
+ Virtualized process table with sorting and selection
+
+ Process Name
+ Window Title
+ CPU Usage
+ Memory Usage
+
+ Affinity staged in the UI. It is not applied until Apply Affinity is clicked.
+ Affinity currently reported by Windows for the selected process
+ Read-only preview of current or pending CPU selection
+ Open CPU Masks tab to create a new custom mask
+ Shows whether Hyper-Threading (Intel) or SMT (AMD) is present and active on this system
+
+ Copy Process Info
+ Open Executable Location
+ Clear CPU Sets
+ Apply Pending Settings
+ Apply the pending affinity and selected power plan to the selected process
+ Rules and changes are applied by ThreadPilot only when configured.
+ Current process status
+ Advanced affinity picker
+ Select the pending mask for row context-menu affinity actions
+ Selected power plan
+ Save as Rule
+ No visible window title
+ Batch
+ total)
+ Priority
+ CPU: unavailable
+ Memory: unavailable
+ CPU priority: unavailable
+ Memory priority unavailable
+ Affinity: unavailable
+ No saved rule
+ No recent ThreadPilot action
+ Selected process: {0} (PID {1})
+ Current process status: protected or access denied
+ Current process status: selected
+ CPU: {0:N1}%
+ Memory: {0}
+ CPU priority: {0}
+ Affinity: legacy mask 0x{0:X}
+ Memory priority: {0}
+ saved rule
+ Saved rule exists: {0}
+
+ Above Normal
+ Below Normal
+ High
+ Idle
+ Low
+ Normal
+ Realtime
+ Batch
+ Custom
+
+ Has Window
+ Window
+ PID
+ ID
+ Memory (MB)
+ Affinity
+ Priority
+ Rules
+ Name
+ Set Memory Priority
+ Very Low
+ Medium
+ Refresh Process Info
+
+
+ Application Settings
+ Configure notifications, system tray, and application behavior
+ Notifications
+ Enable notifications
+ Notification Level
+ All
+ Warnings/Errors only
+ Silent
+ Enable balloon notifications (system tray)
+ Enable toast notifications (Windows 10+)
+ Notification Types
+ Power plan changes
+ Process monitoring events
+ Error notifications
+ Success notifications
+ Duration (ms):
+ Test Notification
+
+ System Tray
+ Show tray icon
+ Minimize to tray
+ Close to tray (instead of exit)
+ Start minimized
+ Enable pending settings apply from tray
+ Enable automation monitoring controls from tray
+ Show detailed tooltips
+
+ Basic Preferences
+ Autostart
+ Start with Windows
+ Automatically start ThreadPilot when Windows starts
+ Low impact mode in background
+ Lower ThreadPilot's process priority while minimized or hidden to tray.
+
+ Appearance
+ Use dark theme
+ Applies a global Dark/Light theme across all tabs
+
+ Language
+ 简体中文 (Simplified Chinese)
+ English (English)
+ Applies a global display language across the entire application interface.
+
+ Rules & automation
+ Saved rule auto-apply
+ Apply saved rules when matching processes start
+ Applies enabled saved rules while ThreadPilot is running. This does not install a Windows Service and does not use registry/IFEO persistence.
+ Enable WMI process events
+ Use Windows Management Instrumentation for process start/stop events
+ Enable fallback polling
+ Use polling as backup when WMI process events fail
+ Polling interval (ms):
+ Fallback polling (ms):
+
+ Advanced
+ Enable notification history
+ Max history items:
+ Auto-hide notifications
+ Enable notification sound
+ Enable debug logging
+ Enable performance counters
+
+ About
+ Version:
+ Copyright © 2026 PrimeBuild
+ Translator: Ylimhs
+ License: AGPLv3
+ Check for updates
+ Download and install update
+ Check automatically on startup
+ Check interval (days):
+ Include prerelease updates
+ Latest version:
+ Last checked:
+ Checks on demand using the official GitHub Releases.
+
+ Reset to Defaults
+ Export Configuration
+ Import Configuration
+ Save Settings
+ ThreadPilot
+ Theme changed to {0}.
+ Failed to change theme to {0}.
+ Language changed to {0}.
+ Failed to change language.
+ Saving settings...
+ Settings saved with warnings: {0}
+ Settings saved and applied successfully.
+ Error saving settings: {0}
+ Resetting to defaults...
+ Settings reset to defaults (not saved yet)
+ Error resetting settings: {0}
+ Exporting configuration bundle...
+ Export canceled
+ Configuration exported to: {0}
+ Error exporting settings: {0}
+ Importing configuration...
+ Import canceled
+ Configuration bundle imported and applied
+ Legacy settings imported (rules unchanged)
+ Error importing settings: {0}
+ Test notification sent
+ Error sending test notification: {0}
+ Loading settings...
+ Settings loaded
+ Error loading settings: {0}
+ Settings synchronized
+ Checking for updates...
+ Unable to determine the latest version.
+ New version available: {0}
+ Application is up to date. Installed version: {0}
+ Error while checking updates: {0}
+ Unknown
+ Not checked
+ Never
+ Install ThreadPilot update
+ ThreadPilot will download and verify version {0}, then ask Windows for permission to run the installer. Continue?
+ Update canceled.
+ Downloading and verifying update...
+ Update installer started.
+ Update install failed: {0}
+ Settings have been modified
+ Settings match the saved configuration
+ Simplified Chinese
+ English
+ Dark
+ Light
+ Export ThreadPilot Configuration
+ Import ThreadPilot Configuration
+ Failed to update Windows autostart. Keeping previous autostart state.
+
+
+ ThreadPilot Settings
+ Unsaved Settings
+ You have unsaved changes. Save before closing, discard the changes, or cancel to keep editing.
+ Cancel
+ Discard
+ Save
+
+
+ System Tweaks & Optimizations
+ Configure Windows system optimizations and performance tweaks
+ Refresh All
+ Refresh all tweak states
+ Toggle this Windows tweak
+ Status
+
+
+ Core Parking
+ Controls CPU core parking for power management
+ C-States
+ Controls CPU C-States for power management
+ SysMain Service
+ Windows Superfetch/SysMain service for memory management
+ Prefetch
+ Windows Prefetch feature for faster application loading
+ Power Throttling
+ Windows Power Throttling for energy efficiency
+ HPET
+ High Precision Event Timer for system timing
+ High Scheduling Category
+ High scheduling priority for gaming applications
+ Menu Show Delay
+ Delay before showing context menus
+
+
+ Ready
+ Refreshing system tweaks...
+ Last refreshed: {0}
+ Failed to refresh system tweaks
+ Refresh failed
+ Toggling {0}...
+ {0} enabled successfully
+ {0} disabled successfully
+ {0} has been enabled
+ {0} has been disabled
+ System Tweak Updated
+ Failed to toggle {0}
+ Failed to enable {0}
+ Failed to disable {0}
+ System Tweak Failed
+ Failed to {0} {1}
+ Error toggling {0}
+ Error toggling {0}: {1}
+ enable
+ disable
+ enabled
+ disabled
+ Enabled
+ Disabled
+ Not Available
+ Loading system tweaks...
+ System tweaks loaded successfully
+
+
+ Open Dashboard
+ Open Diagnostics
+ Pause Automation Monitoring
+ Resume Automation Monitoring
+ System Status
+ No process selected
+ Selected: {0}
+ Apply Pending Settings to Selected Process
+ Apply Pending Settings to {0}
+ 🔋 Power Plans
+ 📋 Profiles
+ Settings
+ Exit
+ No profiles available
+ Power Plan: {0}
+ Automation WMI Error
+ Automation Active
+ Automation Disabled
+ Unknown
+ 💻 CPU: {0:F1}% | RAM: {1:F1}% | {2}
+
+
+ Windows denied this change. The process may require administrator rights or may be protected.
+ The process appears protected by anti-cheat or process protection. ThreadPilot will not try to bypass it.
+ Administrator mode may help with normal permission issues, but cannot bypass anti-cheat or protected process restrictions.
+ This CPU selection cannot be safely represented by legacy affinity APIs on this topology. CPU Sets are required for this selection.
+ This CPU selection does not match the current CPU topology. Review or recreate the preset.
+ The process exited before ThreadPilot could apply the change.
+ Windows CPU Sets are unavailable or rejected this selection. ThreadPilot will use a safe fallback only when possible.
+ High priority can improve responsiveness for some workloads but may reduce system responsiveness.
+ Realtime priority is blocked by ThreadPilot because it can make Windows unstable or unresponsive.
+ Persistent launch-time priority may be supported for normal processes, but it does not bypass protected process or anti-cheat restrictions.
+ Applies saved rules when a matching process starts. Some protected or anti-cheat processes may reject changes. Administrator mode can help with normal permission issues but cannot bypass protection.
+ The process appears protected by anti-cheat or process protection. ThreadPilot will not try to override it.
+
+
+ Power Plan Changed
+ Power plan changed from '{0}' to '{1}'
+ Power plan changed to '{0}' for process '{1}'
+ Process Monitoring Enabled
+ Process Monitoring Disabled
+ CPU Affinity Applied
+ CPU affinity set for '{0}': {1}
+ Game Boost Activated
+ Game Boost mode activated for {0}
+ Game Boost Deactivated
+ Game Boost mode deactivated after {0}
+ Process Monitor Error
+ Affinity blocked
+ Affinity applied
+ Affinity adjusted
+ Affinity failed
+ Affinity error
+ Priority blocked
+ Priority warning
+ Priority applied
+ Priority adjusted
+ Priority error
+ Keyboard Shortcut
+ Toggle monitoring shortcut activated
+ High Performance power plan shortcut activated
+ Refresh process list shortcut activated
+ ThreadPilot Started
+ Process monitoring and power plan management is now active
+ Startup Error
+ Failed to start process monitoring manager
+ Automation Monitoring Error
+ Settings Saved
+ Application settings have been saved successfully
+ Settings Saved with Warnings
+ Settings Error
+ Failed to save settings
+ This is a test notification to verify your settings are working correctly.
+
+
+ ThreadPilot requires administrator privileges to manage process affinity and power plans.
Would you like to restart the application with administrator privileges?
+ Administrator Privileges Required
+ Failed to restart with administrator privileges. Please manually run ThreadPilot as administrator.
+ Elevation Failed
+ Running with Administrator privileges
+ Running with limited privileges
+
+
+ Could not query Core Parking value via powercfg
+ Could not query C-States value via powercfg
+ Prefetch registry key not found
+ Power Throttling not available on this system
+ PriorityControl registry key not found
+ Desktop registry key not found
+
diff --git a/Locales/zh-CN.xaml b/Locales/zh-CN.xaml
new file mode 100644
index 0000000..d3cc1fa
--- /dev/null
+++ b/Locales/zh-CN.xaml
@@ -0,0 +1,655 @@
+
+
+
+ ThreadPilot - 进程与电源计划管理器
+ 推荐以管理员权限运行
+ ThreadPilot 当前正以受限权限运行。某些功能可能无法使用。
+ 需要管理员访问权限以执行以下操作:
+ • 修改电源计划配置
+ • 更改进程 CPU 关联性和优先级
+ • 应用系统级优化和调整
+ • 管理受保护的进程
+ 不提升权限继续
+ 请求权限提升
+
+
+ 进程管理
+ CPU 掩码
+ 电源计划
+ 自动化规则
+ 性能诊断
+ 活动日志
+ 系统微调
+ 应用设置
+
+
+ 启动时最小化
+ 开启此项后,ThreadPilot 会在 Windows 登录时静默启动至系统托盘。
+ 推荐
+ 不再显示
+ 打开设置
+ 主导航
+ 权限提升警告覆盖层
+ 性能诊断介绍覆盖层
+ 启动时最小化建议
+ 未保存设置对话框
+ 应用启动加载覆盖层
+
+
+ ThreadPilot 活动日志
+ 显示 ThreadPilot 执行的操作,包括已应用规则、关联性更改、优先级更改、电源计划更改、设置更改、调整、优化以及安全故障消息。
+ 搜索:
+ 类别:
+ 级别:
+ 从:
+ 至:
+ 刷新
+ 清除显示
+ 导出活动
+ 清理诊断文件
+ 打开诊断文件夹
+
+
+ 时间
+ 状态
+ 类别
+ 消息
+ 详情
+ ID
+ 复制条目
+ 刷新
+ 没有要显示的日志条目
+ 调整过滤器或刷新日志以加载最近的 ThreadPilot 活动。
+
+
+ 活动详情
+ 时间戳:
+ 状态:
+ 类别:
+ 消息:
+ 详情:
+ 相关性 ID:
+ 未选择日志条目
+ 文件:
+ 大小:
+ 调试诊断
+ 最大大小 (MB):
+ 保留天数 (天):
+ 保存设置
+
+
+ CPU 掩码
+ 创建可复用的 CPU 关联性预设以供每个进程使用。
+ 在此处选择掩码仅编辑预设。在将其应用于进程或保存在进程规则中之前,它不会更改 CPU 关联性。
+ 新建
+ 删除
+ 复制掩码
+ 掩码信息
+ 名称:
+ 描述:
+ 已启用
+ 默认预设
+ 当 ThreadPilot 需要后备掩码或创建针对每个进程的规则时预先选择。它不会自动应用 CPU 关联性。
+ 禁用以暂时隐藏此掩码
+ 选择 CPU 核心
+ 切换 CPU 以编辑此掩码预设。更改将自动保存,且不会影响正在运行的进程。“所有核心”是受保护的默认预设。
+ 掩码名称、描述、CPU 选择和选项会自动保存。
+ 创建新的 CPU 掩码
+ 删除选定的掩码
+ CPU 核心
+ CPU
+ 掩码选项
+
+
+ 可选性能诊断
+ 诊断是可选的,仅用于故障排除。对于游戏内覆盖层和详细的性能图表,请使用专用工具。
+ 诊断是可选的,仅用于故障排除。
+ 对于游戏内覆盖层和详细的性能图表,请使用专用工具。
+ 快速提示:
+ 1. 仅在需要针对性的故障排除快照时才打开诊断。
+ 2. 在创建自动化规则之前,仅将热点查看作为提示。
+ 3. 故障排除完成后,停止实时指标收集。
+ 继续前往诊断
+
+ 活动进程
+ 通过一键规则创建来监控 CPU 和内存的占用大户。
+ 按名称搜索进程
+ 仅限包含规则的
+ 仅限可操作的
+ 规则影响
+ 基于选择创建/更新规则
+ 为选定的热点进程创建或更新自动化规则
+
+ 稳定性时间线
+ 清除历史记录
+ 清除显示的指标和时间轴历史记录
+ 核心快照
+ 单核利用率,用于快速的不平衡检查。
+ 切换核心面板
+ 切换进程面板
+ 开始实时指标
+ 为此控制面板启动实时指标收集
+ 停止实时指标
+ 暂停实时指标收集;后台自动化会单独运行
+ 刷新
+ 刷新当前的仪表板快照
+
+ 全局电源计划
+ 进程热点
+ 筛选
+ 内存
+ 名称
+ 优先级
+ 窗口
+ 已用内存
+ CPU %
+ 内存 %
+ 线程数
+ 事件
+ 严重性
+ 详情
+ 时间
+ 类别
+ 进程
+ 选定的热点进程
+ 指标
+ 进程
+
+
+ 电源计划管理
+ 管理活动的 Windows 电源计划并导入自定义 .pow 配置文件
+ Windows 电源计划
+ 选择要激活的 Windows 电源计划。
+ 设为活动 Windows 电源计划
+ 将活动的 Windows 电源计划更改为所选计划
+ 刷新计划
+ 刷新可用电源计划的列表
+ 自定义电源计划
+ 已准备好导入 Windows 的本地 .pow 文件。
+ 导入选中的 .pow
+ 将所选的自定义 .pow 文件导入 Windows
+ 添加 .pow 文件
+ 向自定义库添加新的自定义电源计划文件
+ 删除
+ 活动
+
+
+ 规则与自动化
+ 自动化监控监视进程的启动/停止事件,并应用配置的电源计划、CPU 掩码和优先级规则。
+ 规则编辑器
+ 从可执行文件或运行中的进程创建规则,以实现电源计划、CPU 掩码和优先级行为的自动化。
+ 可执行文件匹配:
+ 按路径匹配
+ 按完整路径而不是仅按可执行文件名称匹配进程
+ 浏览可执行文件
+ 点击以从您的计算机选择可执行文件 (.exe)
+ 选择可执行文件。按路径匹配更精确;按名称匹配适用于任何具有该可执行文件名称的进程。
+ 使用运行中的进程:
+ 选择当前运行的进程以使用其可执行文件
+ 使用所选进程
+ 使用所选运行中进程的可执行文件
+ 规则电源计划 (全局切换):
+ 当此规则匹配时,Windows 将切换全局活动电源计划。
+ 规则 CPU 掩码:
+ 可选: 选择在该进程启动时要应用的 CPU 掩码
+ 规则优先级
+ 更新
+ 可选: 选择在该进程启动时要应用的进程优先级
+ 关联优先级:
+ 当有多个匹配时,优先级较高的关联优先使用
+ 添加规则
+ 更新选定规则
+ 更新所选的关联
+ 清除选择
+ 清除选定的可执行文件
+
+ 当前规则
+ 定义针对每个进程的规则。电源计划是全局的;掩码和优先级适用于匹配的进程。
+ 删除
+ 删除所选关联
+ 默认电源计划 (当无规则匹配时的后备方案)
+ 当没有关联的进程在运行时要使用的电源计划:
+ 设置默认电源计划
+
+ 自动化监控设置
+ 启用基于事件的自动化 (WMI)
+ 启用自动化后备轮询
+ 轮询间隔 (秒):
+ 电源计划切换延迟 (毫秒):
+ 防止重复更改电源计划
+ 保存配置
+ 尚无自动化规则
+ 状态:
+ 自动化监控
+ 启动自动化监控
+ 停止自动化监控
+
+ 在运行自动化规则时应用于每个匹配的进程。
+ 仅应用于匹配的进程;它不会更改全局 Windows 电源计划。
+ 选定的可执行文件:
+ 描述:
+ 自动化服务
+ 规则
+ 可执行文件
+ 电源计划
+ CPU 掩码
+ 优先级
+ 描述
+ 进程优先级:
+
+
+ 系统进程管理
+ 搜索、过滤和控制活动的进程配置
+ 按名称搜索进程
+ 进程搜索
+ 隐藏 Windows 系统进程
+ 隐藏系统进程
+ 隐藏 CPU 使用率极低的进程
+ 隐藏空闲进程
+ 仅显示具有可见窗口的应用程序
+ 仅限活动应用
+ 锁定进程列表
+ 在您处理当前列表时暂停进程列表刷新和排序更新。ThreadPilot 运行时,后台监控和保存的规则自动应用仍将继续。
+ 排序方式:
+ 选择如何对进程列表进行排序
+
+ 选定的进程
+ 未选择进程
+ 从表格中选择一个进程以启用关联性、优先级、电源计划和规则操作。
+ 电源计划 / 待处理设置
+ 选择要手动激活的电源计划,或包含在快速应用中
+ 设置电源计划
+ 激活所选的 Windows 电源计划
+
+ 待处理的核心掩码
+ 选择一个掩码来暂存它。在点击“应用关联性”之前,这不会更改操作系统关联性。
+ 应用关联性
+ 将待处理的核心掩码应用于选定的进程,并验证 Windows 关联性状态
+ 应用关联性并保存为规则
+ 将当前进程设置保存为规则。以后此进程启动时将自动应用这些设置。
+
+ 设置 CPU 优先级
+ 将所选优先级应用于进程
+ 通过注册表强制执行优先级
+ 通过 Windows 注册表应用优先级。必须重新启动进程才能使更改生效。此设置在系统重启后仍然有效。
+ 设置优先级
+ 实时优先级已被 ThreadPilot 阻止,因为它可能会使 Windows 不稳定或无响应。
+ 实时 (已阻止)
+
+ 禁用空闲服务
+ 在此进程运行时阻止系统进入空闲状态。适用于游戏和对性能要求严苛的应用程序。
+
+ 配置文件 / 规则
+ 输入配置文件名称以保存或加载设置
+ 保存配置文件
+ 将当前 CPU 关联性和优先级保存为可复用的配置文件
+ 加载配置文件
+ 加载以前保存的配置文件
+ 保存当前设置为规则
+
+ 最后一次 ThreadPilot 操作:
+ 刷新
+ 刷新进程列表
+ 加载更多
+ 加载更多进程
+ 刷新进程
+ 加载更多进程
+ 运行中进程列表
+ 支持排序和选择的虚拟化进程表
+
+ 进程名称
+ 窗口标题
+ CPU 使用率
+ 内存使用
+
+ 关联性已暂存在 UI 中。在点击“应用关联性”之前不会应用。
+ Windows 当前报告的所选进程的关联性
+ 当前或待处理 CPU 选择的只读预览
+ 打开 CPU 掩码选项卡以创建新的自定义掩码
+ 显示此系统上是否具有并启用了超线程 (Intel) 或 SMT (AMD)
+
+ 复制进程信息
+ 打开可执行文件位置
+ 清除 CPU 集
+ 应用待处理设置
+ 将待处理的关联性和选定的电源计划应用于选定的进程
+ ThreadPilot 仅在配置后才应用规则和更改。
+ 当前进程状态
+ 高级关联性选择器
+ 为行上下文菜单关联性操作选择待处理掩码
+ 所选电源计划
+ 保存为规则
+ 无可见窗口标题
+ 批次
+ 总计)
+ 优先级
+ CPU: 不可用
+ 内存: 不可用
+ CPU 优先级: 不可用
+ 内存优先级不可用
+ 关联性: 不可用
+ 无已保存规则
+ 暂无最近的 ThreadPilot 操作
+ 选定进程: {0} (PID {1})
+ 当前进程状态: 受保护或访问被拒绝
+ 当前进程状态: 已选择
+ CPU: {0:N1}%
+ 内存: {0}
+ CPU 优先级: {0}
+ 关联性: 旧版掩码 0x{0:X}
+ 内存优先级: {0}
+ 已保存规则
+ 存在已保存规则: {0}
+
+ 高于正常
+ 低于正常
+ 高
+ 空闲
+ 低
+ 正常
+ 实时
+ 批处理
+ 自定义
+
+ 有窗口
+ 窗口
+ PID
+ ID
+ 内存 (MB)
+ 关联性
+ 优先级
+ 规则
+ 名称
+ 设置内存优先级
+ 极低
+ 中
+ 刷新进程信息
+
+
+ ThreadPilot 系统设置
+ 配置通知、系统托盘和应用程序行为
+ 系统通知
+ 启用应用通知
+ 通知级别
+ 全部显示
+ 仅警告与错误
+ 静音模式
+ 启用系统托盘气泡通知
+ 启用 Windows 吐司通知 (Windows 10+)
+ 通知事件类别
+ 电源计划变更
+ 进程监控事件
+ 错误与异常通知
+ 操作成功提示
+ 持续显示时间 (毫秒):
+ 测试通知发送
+
+ 系统托盘栏
+ 显示托盘图标
+ 最小化到托盘
+ 关闭主窗口时最小化到托盘
+ 开机启动时最小化
+ 允许从托盘菜单应用待处理设置
+ 允许从托盘菜单控制自动化监控
+ 托盘图标显示详细鼠标提示
+
+ 基本偏好设置
+ 系统开机启动
+ 随 Windows 开机启动
+ 在 Windows 系统启动时自动开启 ThreadPilot
+ 后台低系统影响模式
+ 在最小化或隐藏至托盘时自动降低 ThreadPilot 的进程优先级。
+
+ 外观主题
+ 启用暗黑主题
+ 在所有选项卡上全局应用 亮色/暗色 视觉风格
+
+ 显示语言
+ 简体中文 (Simplified Chinese)
+ English (English)
+ 在整个应用程序界面应用全局的语言设置。
+
+ 规则与自动化
+ 保存规则自动应用
+ 在匹配的进程启动时自动应用已保存规则
+ 在 ThreadPilot 运行时自动应用已启用的保存规则。这不会注册 Windows 服务,也不使用注册表/IFEO 进行常驻。
+ 启用 WMI 进程启动监控
+ 使用 Windows Management Instrumentation 来监听进程启动/退出事件
+ 启用后备轮询监控
+ 如果 WMI 进程事件订阅失败,自动启用定时轮询作为备份
+ 轮询间隔时间 (毫秒):
+ 后备轮询间隔时间 (毫秒):
+
+ 高级与调试设置
+ 启用通知历史记录
+ 最大历史条目数:
+ 自动渐隐通知气泡
+ 播放提示音
+ 开启调试诊断日志记录
+ 启用内部性能计数器
+
+ 关于应用
+ 软件版本:
+ 版权所有 © 2026 PrimeBuild
+ 翻译人员:Ylimhs
+ 软件授权: AGPLv3
+ 检查新版本
+ 下载并安装更新
+ 启动时自动检查更新
+ 检查间隔(天):
+ 包含预发布版本
+ 最新版本:
+ 上次检查:
+ 按需通过官方 GitHub Releases API 检索最新稳定版本。
+
+ 重置为默认值
+ 导出配置包
+ 导入配置包
+ 保存并应用设置
+ ThreadPilot
+ 主题已切换为{0}。
+ 无法切换主题为{0}。
+ 语言已切换为{0}。
+ 无法切换语言。
+ 正在保存设置...
+ 设置已保存但有警告: {0}
+ 设置已成功保存并应用。
+ 保存设置时出错: {0}
+ 正在重置为默认值...
+ 设置已重置为默认值(尚未保存)
+ 重置设置时出错: {0}
+ 正在导出配置包...
+ 已取消导出
+ 配置已导出到: {0}
+ 导出设置时出错: {0}
+ 正在导入配置...
+ 已取消导入
+ 配置包已导入并应用
+ 旧版设置已导入(规则未更改)
+ 导入设置时出错: {0}
+ 测试通知已发送
+ 发送测试通知时出错: {0}
+ 正在加载设置...
+ 设置已加载
+ 加载设置时出错: {0}
+ 设置已同步
+ 正在检查更新...
+ 无法确定最新版本。
+ 发现新版本: {0}
+ 应用已是最新版本。已安装版本: {0}
+ 检查更新时出错: {0}
+ 未知
+ 尚未检查
+ 从未检查
+ 安装 ThreadPilot 更新
+ ThreadPilot 将下载并验证版本 {0},然后请求 Windows 权限运行安装程序。是否继续?
+ 更新已取消。
+ 正在下载并验证更新...
+ 更新安装程序已启动。
+ 更新安装失败: {0}
+ 设置已被修改
+ 设置与已保存的配置一致
+ 简体中文
+ 英文
+ 深色
+ 浅色
+ 导出 ThreadPilot 配置
+ 导入 ThreadPilot 配置
+ 无法更新 Windows 自启动。将保留之前的自启动状态。
+
+
+ ThreadPilot 设置
+ 未保存的设置
+ 您有尚未保存的更改。请选择在关闭前保存、放弃修改或取消并返回编辑。
+ 取消
+ 放弃更改
+ 保存
+
+
+ 系统微调与优化
+ 配置 Windows 系统级优化项和性能微调选项
+ 刷新状态
+ 刷新所有微调选项的状态
+ 切换此 Windows 系统微调项
+ 当前状态
+
+
+ 核心休眠 (Core Parking)
+ 控制 CPU 核心休眠以进行电源管理
+ C-States 状态
+ 控制 CPU C-States 以进行节能电源管理
+ SysMain 服务
+ Windows Superfetch/SysMain 服务,用于内存管理
+ 预取 (Prefetch)
+ Windows Prefetch 功能,用于加速应用程序加载
+ 电源限流 (Power Throttling)
+ Windows 电源限流功能,用于能效优化
+ HPET 定时器
+ 高精度事件计时器,用于系统精准定时
+ 高调度优先级类别
+ 为游戏应用程序提供高调度优先级
+ 菜单显示延迟
+ 显示上下文菜单之前的延迟时间
+
+
+ 就绪
+ 正在刷新系统微调选项...
+ 上次刷新时间: {0}
+ 刷新系统微调失败
+ 刷新失败
+ 正在切换 {0}...
+ {0} 已成功启用
+ {0} 已成功禁用
+ {0} 已启用
+ {0} 已禁用
+ 系统微调已更新
+ 无法切换 {0}
+ 未能启用 {0}
+ 未能禁用 {0}
+ 系统微调失败
+ 未能{0}{1}
+ 切换 {0} 出错
+ 切换 {0} 时出错: {1}
+ 启用
+ 禁用
+ 启用
+ 禁用
+ 已启用
+ 已禁用
+ 不可用
+ 正在加载系统微调...
+ 系统微调已成功加载
+
+
+ 打开主控制面板
+ 打开性能诊断
+ 暂停自动化监控
+ 恢复自动化监控
+ 系统状态
+ 未选择进程
+ 已选择: {0}
+ 应用待处理设置到所选进程
+ 应用待处理设置到 {0}
+ 🔋 电源计划
+ 📋 配置文件
+ 应用设置
+ 退出程序
+ 无可用配置文件
+ 电源计划: {0}
+ 自动化 WMI 错误
+ 自动化监控已启用
+ 自动化监控已禁用
+ 未知
+ 💻 CPU: {0:F1}% | 内存: {1:F1}% | {2}
+
+
+ Windows 拒绝了此更改。该进程可能需要管理员权限或受保护。
+ 该进程似乎受到反作弊系统或进程保护的保护。ThreadPilot 不会尝试绕过它。
+ 管理员模式可能有助于解决普通的权限问题,但无法绕过反作弊系统或受保护的进程限制。
+ 在此拓扑上,此 CPU 选择无法由传统关联性 API 安全地表示。此选择需要使用 CPU 集。
+ 此 CPU 选择与当前 CPU 拓扑不匹配。请检查或重新创建预设。
+ 在 ThreadPilot 应用更改之前,进程已退出。
+ Windows CPU 集不可用或拒绝了此选择。ThreadPilot 将仅在可能时使用 safe 后备方案。
+ 高优先级可以提高某些工作负载的响应速度,但可能会降低系统整体响应速度。
+ 实时优先级已被 ThreadPilot 阻止,因为它可能会使 Windows 不稳定或无响应。
+ 普通进程可能支持持久的启动时优先级,但这不会绕过受保护进程或反作弊系统的限制。
+ 在匹配的进程启动时应用保存的规则。某些受保护或反作弊进程可能会拒绝更改。管理员模式有助于解决普通权限问题,但无法绕过进程保护。
+ 该进程似乎受到反作弊系统或进程保护的保护。ThreadPilot 不会尝试对其进行改写。
+
+
+ 电源计划已更改
+ 电源计划已从“{0}”更改为“{1}”
+ 已为进程“{1}”将电源计划切换为“{0}”
+ 进程监控已启用
+ 进程监控已禁用
+ CPU 关联性已应用
+ 已为“{0}”设置 CPU 关联性: {1}
+ 游戏加速已启用
+ 已为 {0} 启用游戏加速模式
+ 游戏加速已关闭
+ 游戏加速模式已关闭,持续时间: {0}
+ 进程监控器错误
+ 关联性应用被阻止
+ 关联性已应用
+ 关联性已调整
+ 关联性应用失败
+ 关联性错误
+ 优先级应用被阻止
+ 优先级警告
+ 优先级已应用
+ 优先级已调整
+ 优先级错误
+ 键盘快捷键
+ 切换监控快捷键已触发
+ 高性能电源计划快捷键已触发
+ 刷新进程列表快捷键已触发
+ ThreadPilot 已启动
+ 进程监控和电源计划管理现已激活
+ 启动错误
+ 无法启动进程监控管理器
+ 自动化监控错误
+ 设置已保存
+ 应用设置已成功保存
+ 设置已保存但有警告
+ 设置错误
+ 无法保存设置
+ 这是一条用于验证您的设置是否正常工作的测试通知。
+
+
+ ThreadPilot 需要管理员权限来管理进程关联性和电源计划。
您想以管理员权限重新启动应用程序吗?
+ 需要管理员权限
+ 无法以管理员权限重新启动。请手动以管理员身份运行 ThreadPilot。
+ 权限提升失败
+ 以管理员权限运行中
+ 以受限权限运行中
+
+
+ 无法通过 powercfg 查询核心停车值
+ 无法通过 powercfg 查询 C-States 值
+ 未找到预取注册表键
+ 此系统上不支持电源限流
+ 未找到 PriorityControl 注册表键
+ 未找到 Desktop 注册表键
+
diff --git a/MainWindow.Behaviors.partial.cs b/MainWindow.Behaviors.partial.cs
index a4da578..1c857ee 100644
--- a/MainWindow.Behaviors.partial.cs
+++ b/MainWindow.Behaviors.partial.cs
@@ -157,27 +157,26 @@ private async Task CheckForUpdatesAtStartupAsync()
try
{
this.LogDebug("Startup update check started");
- var checker = this.serviceProvider.GetRequiredService();
- var currentVersion = GetCurrentApplicationVersion();
- var (latest, _) = await checker.GetLatestVersionAsync("PrimeBuild-pc", "ThreadPilot");
+ var updateService = this.serviceProvider.GetRequiredService();
+ var result = await updateService.CheckForUpdatesAsync(new UpdateCheckRequest(UpdateCheckTrigger.Startup));
- if (latest == null)
+ if (result.Status == UpdateCheckStatus.Skipped)
{
- this.LogDebug("Startup update check completed without release information");
+ this.LogDebug($"Startup update check skipped: {result.Message}");
return;
}
- if (latest <= currentVersion)
+ if (!result.IsUpdateAvailable || result.Release == null)
{
- this.LogDebug($"Startup update check complete: installed {currentVersion}, latest {latest}");
+ this.LogDebug($"Startup update check complete: {result.Message}");
return;
}
await this.notificationService.ShowNotificationAsync(
"Update available",
- $"ThreadPilot {latest} is available from GitHub releases.",
+ $"ThreadPilot {result.Release.Version} is available. Open Settings to download and install it.",
NotificationType.Information);
- this.LogDebug($"Startup update check found update: installed {currentVersion}, latest {latest}");
+ this.LogDebug($"Startup update check found update: installed {result.CurrentVersion}, latest {result.Release.Version}");
}
catch (Exception ex)
{
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 7a203ed..c991768 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -10,7 +10,7 @@
mc:Ignorable="d"
ExtendsContentIntoTitleBar="True"
WindowBackdropType="Mica"
- Title="ThreadPilot - Process & Power Plan Manager"
+ Title="{DynamicResource MainWindow_Title}"
Height="864"
Width="1280"
WindowStartupLocation="CenterScreen"
@@ -86,7 +86,7 @@
IsPaneOpen="False"
OpenPaneLength="180"
CompactPaneLength="52"
- AutomationProperties.Name="Primary navigation">
+ AutomationProperties.Name="{DynamicResource MainWindow_PrimaryNavigation}">
-
-
-
+
@@ -290,22 +290,22 @@
-
+
-
+
-
+
-
+
-
-
+
-
-
+
-
+
@@ -168,9 +168,9 @@
-
+
-
-
+
@@ -219,20 +219,20 @@
-
+
-
-
+ ToolTip="{DynamicResource MasksView_DefaultPresetTip}"/>
-
+ ToolTip="{DynamicResource MasksView_DisableTip}"/>
diff --git a/Views/PerformanceView.xaml b/Views/PerformanceView.xaml
index 2279773..a7aa5ff 100644
--- a/Views/PerformanceView.xaml
+++ b/Views/PerformanceView.xaml
@@ -75,33 +75,33 @@
-
-
-
+
+
+
-
-
+
-
+
-
+
+ ToolTip="{DynamicResource PerformanceView_ClearHistoryTooltip}"/>
@@ -124,7 +124,7 @@
-
+
@@ -132,7 +132,7 @@
-
+
@@ -140,7 +140,7 @@
-
+
@@ -169,20 +169,20 @@
-
-
+
+
-
-
+
-
@@ -198,7 +198,7 @@
@@ -215,18 +215,18 @@
Width="110"
Margin="0,0,8,0">
-
-
+
+
@@ -250,12 +250,12 @@
MinHeight="220"
MaxHeight="380">
-
-
-
-
-
-
+
+
+
+
+
+
@@ -303,8 +303,8 @@
-
-
+
+
@@ -320,8 +320,8 @@
-
-
+
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/Views/PowerPlanView.xaml b/Views/PowerPlanView.xaml
index d095797..c8d4bfd 100644
--- a/Views/PowerPlanView.xaml
+++ b/Views/PowerPlanView.xaml
@@ -16,8 +16,8 @@
-
-
+
+
@@ -29,7 +29,7 @@
@@ -43,21 +43,21 @@
+ ToolTip="{DynamicResource PowerPlanView_SelectActiveTip}"/>
+ ToolTip="{DynamicResource PowerPlanView_SetActiveTooltip}"/>
+ ToolTip="{DynamicResource PowerPlanView_RefreshTooltip}"/>
@@ -73,7 +73,7 @@
-
@@ -120,7 +120,7 @@
Padding="8,2"
VerticalAlignment="Top"
Visibility="{Binding IsActive, Converter={StaticResource BoolToVisibilityConverter}}">
-
@@ -135,7 +135,7 @@
@@ -149,21 +149,21 @@
+ ToolTip="{DynamicResource PowerPlanView_LocalPlansTip}"/>
+ ToolTip="{DynamicResource PowerPlanView_ImportSelectedTooltip}"/>
+ ToolTip="{DynamicResource PowerPlanView_AddFileTooltip}"/>
diff --git a/Views/ProcessPowerPlanAssociationView.xaml b/Views/ProcessPowerPlanAssociationView.xaml
index 7f05b0a..47de0e7 100644
--- a/Views/ProcessPowerPlanAssociationView.xaml
+++ b/Views/ProcessPowerPlanAssociationView.xaml
@@ -21,8 +21,8 @@
-
-
+
@@ -62,7 +62,7 @@
-
+
@@ -71,7 +71,7 @@
-
+
@@ -87,28 +87,28 @@
HeadersVisibility="Column"
BorderThickness="1">
-
-
-
-
-
-
-
-
@@ -130,11 +130,11 @@
-
-
-
-
+
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_RemoveTooltip}"/>
-
+
-
-
+
-
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_BrowseTooltip}"/>
-
+
-
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_ClearSelectionTooltip}"/>
-
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_MatchByPathTooltip}"/>
-
-
+
-
-
+
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_RuleCpuMaskHelp}"/>
-
-
+
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_RulePriorityHelp}"/>
-
+
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_AssociationPriorityHelp}"/>
-
+
-
-
-
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_UseRunningProcessTooltip}"/>
-
+ ToolTip="{DynamicResource ProcessPowerPlanAssociationView_UseSelectedProcessTooltip}"/>
@@ -275,29 +275,29 @@
-
+
-
+
-
-
+
-
-
@@ -306,9 +306,9 @@
-
+
-
-
-
+
-
-
-
-
-
-
diff --git a/Views/ProcessView.xaml b/Views/ProcessView.xaml
index e194618..6a734ff 100644
--- a/Views/ProcessView.xaml
+++ b/Views/ProcessView.xaml
@@ -156,8 +156,8 @@
-
-
+
+
@@ -201,53 +201,53 @@
+ AutomationProperties.Name="{DynamicResource ProcessView_SearchAutomationName}"/>
+ ToolTip="{DynamicResource ProcessView_VisibleWindowsOnly}"/>
+ Content="{DynamicResource ProcessView_Refresh}"
+ ToolTip="{DynamicResource ProcessView_RefreshTooltip}"
+ AutomationProperties.Name="{DynamicResource ProcessView_RefreshAutomationName}"/>
+ ToolTip="{DynamicResource ProcessView_LoadMoreTooltip}"
+ AutomationProperties.Name="{DynamicResource ProcessView_LoadMoreAutomationName}"/>
-
-
+
-
+
-
+ ToolTip="{DynamicResource ProcessView_LockListTooltip}"/>
+
-
-
-
-
+ ToolTip="{DynamicResource ProcessView_SortByTooltip}">
+
+
+
+
@@ -269,8 +269,8 @@
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
ScrollViewer.CanContentScroll="True"
- AutomationProperties.Name="Running process list"
- AutomationProperties.HelpText="Virtualized process table with sorting and selection">
+ AutomationProperties.Name="{DynamicResource ProcessView_RunningListAutomationName}"
+ AutomationProperties.HelpText="{DynamicResource ProcessView_RunningListAutomationHelp}">
-
-
-
-
-
-
+
+
+
+
+
-
+
@@ -415,13 +415,13 @@
Padding="8,5"
CornerRadius="{DynamicResource StandardCardCornerRadius}">
-
+
-
+
@@ -434,11 +434,11 @@
Padding="10"
Margin="0,12,0,0">
-
-
-
+
-
@@ -499,7 +499,7 @@
@@ -508,14 +508,14 @@
SelectedItem="{Binding SelectedCoreMask, Mode=TwoWay}"
DisplayMemberPath="Name"
IsEnabled="{Binding SelectedProcess, Converter={StaticResource NullToBoolConverter}}"
- ToolTip="Select the pending mask for row context-menu affinity actions"/>
+ ToolTip="{DynamicResource ProcessView_RowMaskTooltip}"/>
@@ -583,7 +583,7 @@
CornerRadius="8">
-
@@ -595,7 +595,7 @@
Background="{DynamicResource QuietRowBackgroundBrush}"
Margin="0,0,0,12">
-
@@ -610,7 +610,7 @@
-
-
+
-
+
+ ToolTip="{DynamicResource ProcessView_AffinityCurrentTooltip}"/>
+ ToolTip="{DynamicResource ProcessView_AffinityStagedTooltip}"/>
-
+
+ ToolTip="{DynamicResource ProcessView_StageMaskTooltip}">
@@ -700,7 +700,7 @@
FontSize="{StaticResource ProcessFontSmall}"
Margin="0,2,0,6"
Foreground="{Binding IsHyperThreadingActive, Converter={StaticResource BoolToColorConverter}}"
- ToolTip="Shows whether Hyper-Threading (Intel) or SMT (AMD) is present and active on this system"/>
+ ToolTip="{DynamicResource ProcessView_HyperThreadingTooltip}"/>
+ ToolTip="{DynamicResource ProcessView_CpuSelectionPreviewTooltip}"/>
@@ -736,59 +736,59 @@
+ ToolTip="{DynamicResource ProcessView_ApplyAffinityTooltip}"/>
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
+ ToolTip="{DynamicResource ProcessView_DisableIdleServerTooltip}"/>
-
+
-
@@ -796,7 +796,7 @@
SelectedItem="{Binding SelectedPowerPlan, Mode=TwoWay}"
DisplayMemberPath="Name"
Margin="0,0,0,8"
- ToolTip="Choose the power plan to activate manually or include with quick apply"/>
+ ToolTip="{DynamicResource ProcessView_PowerPlanTooltip}"/>
@@ -805,24 +805,24 @@
+ ToolTip="{DynamicResource ProcessView_SetPowerPlanTooltip}"/>
+ ToolTip="{DynamicResource ProcessView_ApplyPendingSettingsTooltip}"/>
-
+
+ ToolTip="{DynamicResource ProcessView_ProfileNamePlaceholder}"/>
@@ -831,21 +831,21 @@
+ ToolTip="{DynamicResource ProcessView_SaveProfileTooltip}"/>
+ ToolTip="{DynamicResource ProcessView_LoadProfileTooltip}"/>
+ ToolTip="{DynamicResource ProcessView_ApplyAffinitySaveRuleTooltip}"/>
diff --git a/Views/SettingsView.xaml b/Views/SettingsView.xaml
index f2b3ba5..bb09a94 100644
--- a/Views/SettingsView.xaml
+++ b/Views/SettingsView.xaml
@@ -40,8 +40,8 @@
-
-
+
@@ -51,54 +51,54 @@
-
+
-
-
+
-
-
-
+
+
+
-
-
-
+
-
-
-
-
@@ -112,7 +112,7 @@
-
+
-