diff --git a/FreeMove/Form1.Designer.cs b/FreeMove/Form1.Designer.cs
index 844620c..be48ec6 100644
--- a/FreeMove/Form1.Designer.cs
+++ b/FreeMove/Form1.Designer.cs
@@ -69,31 +69,35 @@ private void InitializeComponent()
this.reportAnIssueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.gitHubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.lunguToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.zhToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.chineseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.chkBox_createDest = new System.Windows.Forms.CheckBox();
+ this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(12, 34);
+ this.label1.Location = new System.Drawing.Point(12, 31);
this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(63, 13);
+ this.label1.Size = new System.Drawing.Size(65, 12);
this.label1.TabIndex = 0;
this.label1.Text = "Move From:";
//
// textBox_From
//
- this.textBox_From.Location = new System.Drawing.Point(82, 34);
+ this.textBox_From.Location = new System.Drawing.Point(82, 31);
this.textBox_From.Name = "textBox_From";
- this.textBox_From.Size = new System.Drawing.Size(383, 20);
+ this.textBox_From.Size = new System.Drawing.Size(383, 21);
this.textBox_From.TabIndex = 1;
//
// button_BrowseFrom
//
- this.button_BrowseFrom.Location = new System.Drawing.Point(475, 34);
+ this.button_BrowseFrom.Location = new System.Drawing.Point(475, 31);
this.button_BrowseFrom.Name = "button_BrowseFrom";
- this.button_BrowseFrom.Size = new System.Drawing.Size(75, 23);
+ this.button_BrowseFrom.Size = new System.Drawing.Size(75, 21);
this.button_BrowseFrom.TabIndex = 2;
this.button_BrowseFrom.Text = "Browse...";
this.button_BrowseFrom.UseVisualStyleBackColor = true;
@@ -101,9 +105,9 @@ private void InitializeComponent()
//
// button_BrowseTo
//
- this.button_BrowseTo.Location = new System.Drawing.Point(475, 58);
+ this.button_BrowseTo.Location = new System.Drawing.Point(475, 54);
this.button_BrowseTo.Name = "button_BrowseTo";
- this.button_BrowseTo.Size = new System.Drawing.Size(75, 23);
+ this.button_BrowseTo.Size = new System.Drawing.Size(75, 21);
this.button_BrowseTo.TabIndex = 4;
this.button_BrowseTo.Text = "Browse...";
this.button_BrowseTo.UseVisualStyleBackColor = true;
@@ -111,17 +115,17 @@ private void InitializeComponent()
//
// textBox_To
//
- this.textBox_To.Location = new System.Drawing.Point(82, 60);
+ this.textBox_To.Location = new System.Drawing.Point(82, 55);
this.textBox_To.Name = "textBox_To";
- this.textBox_To.Size = new System.Drawing.Size(383, 20);
+ this.textBox_To.Size = new System.Drawing.Size(383, 21);
this.textBox_To.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
- this.label2.Location = new System.Drawing.Point(12, 60);
+ this.label2.Location = new System.Drawing.Point(12, 55);
this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(23, 13);
+ this.label2.Size = new System.Drawing.Size(23, 12);
this.label2.TabIndex = 3;
this.label2.Text = "To:";
//
@@ -131,9 +135,9 @@ private void InitializeComponent()
//
// button_Move
//
- this.button_Move.Location = new System.Drawing.Point(475, 118);
+ this.button_Move.Location = new System.Drawing.Point(475, 109);
this.button_Move.Name = "button_Move";
- this.button_Move.Size = new System.Drawing.Size(75, 23);
+ this.button_Move.Size = new System.Drawing.Size(75, 21);
this.button_Move.TabIndex = 6;
this.button_Move.Text = "Move";
this.button_Move.UseVisualStyleBackColor = true;
@@ -142,18 +146,18 @@ private void InitializeComponent()
// chkBox_originalHidden
//
this.chkBox_originalHidden.AutoSize = true;
- this.chkBox_originalHidden.Location = new System.Drawing.Point(15, 95);
+ this.chkBox_originalHidden.Location = new System.Drawing.Point(15, 88);
this.chkBox_originalHidden.Name = "chkBox_originalHidden";
- this.chkBox_originalHidden.Size = new System.Drawing.Size(154, 17);
+ this.chkBox_originalHidden.Size = new System.Drawing.Size(198, 16);
this.chkBox_originalHidden.TabIndex = 5;
this.chkBox_originalHidden.Text = "Set original folder to hidden";
this.chkBox_originalHidden.UseVisualStyleBackColor = true;
//
// button_Close
//
- this.button_Close.Location = new System.Drawing.Point(12, 118);
+ this.button_Close.Location = new System.Drawing.Point(12, 109);
this.button_Close.Name = "button_Close";
- this.button_Close.Size = new System.Drawing.Size(75, 23);
+ this.button_Close.Size = new System.Drawing.Size(75, 21);
this.button_Close.TabIndex = 7;
this.button_Close.Text = "Close";
this.button_Close.UseVisualStyleBackColor = true;
@@ -163,11 +167,12 @@ private void InitializeComponent()
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.settingsToolStripMenuItem,
+ this.lunguToolStripMenuItem,
this.infoToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
- this.menuStrip1.Size = new System.Drawing.Size(565, 24);
+ this.menuStrip1.Size = new System.Drawing.Size(565, 25);
this.menuStrip1.TabIndex = 8;
this.menuStrip1.Text = "menuStrip1";
//
@@ -178,7 +183,7 @@ private void InitializeComponent()
this.PermissionCheckToolStripMenuItem,
this.safeModeToolStripMenuItem});
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
- this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
+ this.settingsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
this.settingsToolStripMenuItem.Text = "Settings";
//
// checkForUpdateToolStripMenuItem
@@ -187,20 +192,20 @@ private void InitializeComponent()
this.checkNowToolStripMenuItem,
this.checkOnProgramStartToolStripMenuItem});
this.checkForUpdateToolStripMenuItem.Name = "checkForUpdateToolStripMenuItem";
- this.checkForUpdateToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
+ this.checkForUpdateToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.checkForUpdateToolStripMenuItem.Text = "Check for update";
//
// checkNowToolStripMenuItem
//
this.checkNowToolStripMenuItem.Name = "checkNowToolStripMenuItem";
- this.checkNowToolStripMenuItem.Size = new System.Drawing.Size(199, 22);
+ this.checkNowToolStripMenuItem.Size = new System.Drawing.Size(216, 22);
this.checkNowToolStripMenuItem.Text = "Check now";
this.checkNowToolStripMenuItem.Click += new System.EventHandler(this.CheckNowToolStripMenuItem_Click);
//
// checkOnProgramStartToolStripMenuItem
//
this.checkOnProgramStartToolStripMenuItem.Name = "checkOnProgramStartToolStripMenuItem";
- this.checkOnProgramStartToolStripMenuItem.Size = new System.Drawing.Size(199, 22);
+ this.checkOnProgramStartToolStripMenuItem.Size = new System.Drawing.Size(216, 22);
this.checkOnProgramStartToolStripMenuItem.Text = "Check on program start";
this.checkOnProgramStartToolStripMenuItem.Click += new System.EventHandler(this.CheckOnProgramStartToolStripMenuItem_Click);
//
@@ -211,13 +216,13 @@ private void InitializeComponent()
this.fastToolStripMenuItem,
this.fullToolStripMenuItem});
this.PermissionCheckToolStripMenuItem.Name = "PermissionCheckToolStripMenuItem";
- this.PermissionCheckToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
+ this.PermissionCheckToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.PermissionCheckToolStripMenuItem.Text = "Permission check";
//
// noneToolStripMenuItem
//
this.noneToolStripMenuItem.Name = "noneToolStripMenuItem";
- this.noneToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
+ this.noneToolStripMenuItem.Size = new System.Drawing.Size(108, 22);
this.noneToolStripMenuItem.Text = "None";
this.noneToolStripMenuItem.ToolTipText = "Don\'t check any file before moving";
this.noneToolStripMenuItem.Click += new System.EventHandler(this.NoneToolStripMenuItem_Click);
@@ -227,7 +232,7 @@ private void InitializeComponent()
this.fastToolStripMenuItem.Checked = true;
this.fastToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.fastToolStripMenuItem.Name = "fastToolStripMenuItem";
- this.fastToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
+ this.fastToolStripMenuItem.Size = new System.Drawing.Size(108, 22);
this.fastToolStripMenuItem.Text = "Fast";
this.fastToolStripMenuItem.ToolTipText = "Check all .exe and .dll files before moving";
this.fastToolStripMenuItem.Click += new System.EventHandler(this.FastToolStripMenuItem_Click);
@@ -235,7 +240,7 @@ private void InitializeComponent()
// fullToolStripMenuItem
//
this.fullToolStripMenuItem.Name = "fullToolStripMenuItem";
- this.fullToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
+ this.fullToolStripMenuItem.Size = new System.Drawing.Size(108, 22);
this.fullToolStripMenuItem.Text = "Full";
this.fullToolStripMenuItem.ToolTipText = "Check all files before moving";
this.fullToolStripMenuItem.Click += new System.EventHandler(this.FullToolStripMenuItem_Click);
@@ -245,7 +250,7 @@ private void InitializeComponent()
this.safeModeToolStripMenuItem.Checked = true;
this.safeModeToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.safeModeToolStripMenuItem.Name = "safeModeToolStripMenuItem";
- this.safeModeToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
+ this.safeModeToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.safeModeToolStripMenuItem.Text = "Safe mode";
this.safeModeToolStripMenuItem.Click += new System.EventHandler(this.SafeModeToolStripMenuItem_Click);
//
@@ -254,50 +259,81 @@ private void InitializeComponent()
this.infoToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.reportAnIssueToolStripMenuItem,
this.gitHubToolStripMenuItem,
+ this.helpToolStripMenuItem,
this.aboutToolStripMenuItem});
this.infoToolStripMenuItem.Name = "infoToolStripMenuItem";
this.infoToolStripMenuItem.RightToLeft = System.Windows.Forms.RightToLeft.No;
- this.infoToolStripMenuItem.Size = new System.Drawing.Size(40, 20);
+ this.infoToolStripMenuItem.Size = new System.Drawing.Size(43, 21);
this.infoToolStripMenuItem.Text = "Info";
//
// reportAnIssueToolStripMenuItem
//
this.reportAnIssueToolStripMenuItem.Name = "reportAnIssueToolStripMenuItem";
- this.reportAnIssueToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
+ this.reportAnIssueToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.reportAnIssueToolStripMenuItem.Text = "Report an Issue";
this.reportAnIssueToolStripMenuItem.Click += new System.EventHandler(this.ReportAnIssueToolStripMenuItem_Click);
//
// gitHubToolStripMenuItem
//
this.gitHubToolStripMenuItem.Name = "gitHubToolStripMenuItem";
- this.gitHubToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
+ this.gitHubToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.gitHubToolStripMenuItem.Text = "GitHub";
this.gitHubToolStripMenuItem.Click += new System.EventHandler(this.GitHubToolStripMenuItem_Click);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
- this.aboutToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
+ this.aboutToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.aboutToolStripMenuItem.Text = "About";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.AboutToolStripMenuItem_Click);
//
+ // lunguToolStripMenuItem
+ //
+ this.lunguToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.zhToolStripMenuItem,
+ this.chineseToolStripMenuItem});
+ this.lunguToolStripMenuItem.Name = "lunguToolStripMenuItem";
+ this.lunguToolStripMenuItem.Size = new System.Drawing.Size(77, 21);
+ this.lunguToolStripMenuItem.Text = "Language";
+ //
+ // zhToolStripMenuItem
+ //
+ this.zhToolStripMenuItem.Name = "zhToolStripMenuItem";
+ this.zhToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.zhToolStripMenuItem.Text = "English";
+ this.zhToolStripMenuItem.Click += new System.EventHandler(this.zhToolStripMenuItem_Click);
+ //
+ // chineseToolStripMenuItem
+ //
+ this.chineseToolStripMenuItem.Name = "chineseToolStripMenuItem";
+ this.chineseToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.chineseToolStripMenuItem.Text = "Chinese";
+ this.chineseToolStripMenuItem.Click += new System.EventHandler(this.chineseToolStripMenuItem_Click);
+ //
// chkBox_createDest
//
this.chkBox_createDest.AutoSize = true;
this.chkBox_createDest.Checked = true;
this.chkBox_createDest.CheckState = System.Windows.Forms.CheckState.Checked;
- this.chkBox_createDest.Location = new System.Drawing.Point(175, 95);
+ this.chkBox_createDest.Location = new System.Drawing.Point(219, 88);
this.chkBox_createDest.Name = "chkBox_createDest";
- this.chkBox_createDest.Size = new System.Drawing.Size(140, 17);
+ this.chkBox_createDest.Size = new System.Drawing.Size(174, 16);
this.chkBox_createDest.TabIndex = 9;
this.chkBox_createDest.Text = "Create destination folder";
this.chkBox_createDest.UseVisualStyleBackColor = true;
//
+ // helpToolStripMenuItem
+ //
+ this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
+ this.helpToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.helpToolStripMenuItem.Text = "Help";
+ this.helpToolStripMenuItem.Click += new System.EventHandler(this.HelpToolStripMenuItem_Click);
+ //
// Form1
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(565, 150);
+ this.ClientSize = new System.Drawing.Size(565, 138);
this.Controls.Add(this.chkBox_createDest);
this.Controls.Add(this.button_Close);
this.Controls.Add(this.chkBox_originalHidden);
@@ -350,6 +386,10 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem fastToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem fullToolStripMenuItem;
public System.Windows.Forms.CheckBox chkBox_createDest;
+ private System.Windows.Forms.ToolStripMenuItem lunguToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem zhToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem chineseToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
}
}
diff --git a/FreeMove/Form1.cs b/FreeMove/Form1.cs
index 242a1d8..8d6e7b9 100644
--- a/FreeMove/Form1.cs
+++ b/FreeMove/Form1.cs
@@ -43,8 +43,12 @@ public Form1()
private async void Form1_Load(object sender, EventArgs e)
{
+ ApplyLanguage();
SetToolTips();
+
+
+
//Check whether the program is set to update on its start
if (Settings.AutoUpdate)
{
@@ -77,6 +81,57 @@ private async void Form1_Load(object sender, EventArgs e)
#endregion
+ ///
+ /// 根据当前 UI 语言刷新界面上的文本(按钮/菜单/标签等)
+ ///
+ private void ApplyLanguage()
+ {
+ // 窗口标题
+ Text = Properties.Resources.ResourceManager.GetString("Form_Title");
+
+ // 标签和按钮
+ label1.Text = Properties.Resources.ResourceManager.GetString("Label_From");
+ label2.Text = Properties.Resources.ResourceManager.GetString("Label_To");
+ button_BrowseFrom.Text = Properties.Resources.ResourceManager.GetString("Button_Browse");
+ button_BrowseTo.Text = Properties.Resources.ResourceManager.GetString("Button_Browse");
+ button_Move.Text = Properties.Resources.ResourceManager.GetString("Button_Move");
+ button_Close.Text = Properties.Resources.ResourceManager.GetString("Button_Close");
+ chkBox_originalHidden.Text = Properties.Resources.ResourceManager.GetString("Checkbox_OriginalHidden");
+ chkBox_createDest.Text = Properties.Resources.ResourceManager.GetString("Checkbox_CreateDest");
+
+ // 菜单
+ settingsToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Settings");
+ infoToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Info");
+ lunguToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Language");
+
+ checkForUpdateToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_CheckForUpdate");
+ checkNowToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_CheckNow");
+ checkOnProgramStartToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_CheckOnStart");
+
+ PermissionCheckToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_PermissionCheck");
+ safeModeToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_SafeMode");
+
+ noneToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_None");
+ fastToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Fast");
+ fullToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Full");
+
+ reportAnIssueToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_ReportIssue");
+ gitHubToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_GitHub");
+ aboutToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_About");
+ helpToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("HelpButtonText");
+
+ zhToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Lang_English");
+ chineseToolStripMenuItem.Text = Properties.Resources.ResourceManager.GetString("Menu_Lang_Chinese");
+
+ // 语言菜单打勾状态
+ string lang = Settings.Language;
+ // lang 为空时:跟随系统,这里根据当前 Culture 判定
+ string current = System.Globalization.CultureInfo.CurrentUICulture.Name;
+ bool isChinese = (!string.IsNullOrEmpty(lang) ? lang : current).StartsWith("zh", StringComparison.OrdinalIgnoreCase);
+ zhToolStripMenuItem.Checked = !isChinese;
+ chineseToolStripMenuItem.Checked = isChinese;
+ }
+
private bool PreliminaryCheck(string source, string destination)
{
//Check for errors before copying
@@ -84,14 +139,14 @@ private bool PreliminaryCheck(string source, string destination)
{
IOHelper.CheckDirectories(source, destination, safeMode);
}
- catch(AggregateException ae)
+ catch (AggregateException ae)
{
var msg = "";
foreach (var ex in ae.InnerExceptions)
{
msg += ex.Message + "\n";
}
- MessageBox.Show(msg, "Error");
+ MessageBox.Show(msg, Properties.Resources.ResourceManager.GetString("ErrorTitle"));
return false;
}
return true;
@@ -117,11 +172,12 @@ private async void Begin()
olddir.Attributes = attrib | FileAttributes.Hidden;
}
- MessageBox.Show(this, "Done!");
+ MessageBox.Show(this, Properties.Resources.ResourceManager.GetString("DoneMessage"));
}
catch (IO.MoveOperation.CopyFailedException ex)
{
- switch (MessageBox.Show(this, string.Format($"Do you want to undo the changes?\n\nDetails:\n{ex.InnerException.Message}"), ex.Message, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1))
+ string question = string.Format(Properties.Resources.ResourceManager.GetString("UndoChangesDetailsQuestion"), ex.InnerException.Message);
+ switch (MessageBox.Show(this, question, ex.Message, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1))
{
case DialogResult.Yes:
try
@@ -130,7 +186,7 @@ private async void Begin()
}
catch (Exception ie)
{
- MessageBox.Show(this, ie.Message, "Could not remove copied contents. Try removing manually");
+ MessageBox.Show(this, ie.Message, Properties.Resources.ResourceManager.GetString("RemoveCopiedContentsFailed"));
}
break;
case DialogResult.No:
@@ -140,7 +196,8 @@ private async void Begin()
}
catch (IO.MoveOperation.DeleteFailedException ex)
{
- switch (MessageBox.Show(this, string.Format($"Do you want to undo the changes?\n\nDetails:\n{ex.InnerException.Message}"), ex.Message, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1))
+ string question = string.Format(Properties.Resources.ResourceManager.GetString("UndoChangesDetailsQuestion"), ex.InnerException.Message);
+ switch (MessageBox.Show(this, question, ex.Message, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1))
{
case DialogResult.Yes:
try
@@ -149,7 +206,7 @@ private async void Begin()
}
catch (Exception ie)
{
- MessageBox.Show(this, ie.Message, "Could not move back contents. Try moving manually");
+ MessageBox.Show(this, ie.Message, Properties.Resources.ResourceManager.GetString("MoveBackFailedMessage"));
}
break;
case DialogResult.No:
@@ -159,11 +216,14 @@ private async void Begin()
}
catch (IO.MoveOperation.MoveFailedException ex)
{
- MessageBox.Show(this, string.Format($"Details:\n{ex.InnerException.Message}"), ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ string details = string.Format(Properties.Resources.ResourceManager.GetString("MoveFailedDetailsFormat"), ex.InnerException.Message);
+ MessageBox.Show(this, details, ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (OperationCanceledException)
{
- switch (MessageBox.Show(this, string.Format($"Do you want to undo the changes?"), "Cancelled", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
+ string question = Properties.Resources.ResourceManager.GetString("UndoChangesSimpleQuestion");
+ string title = Properties.Resources.ResourceManager.GetString("CancelledTitle");
+ switch (MessageBox.Show(this, question, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
{
case DialogResult.Yes:
try
@@ -185,7 +245,7 @@ private async void Begin()
private async Task BeginMove(string source, string destination)
{
//Move files
- using (ProgressDialog progressDialog = new ProgressDialog("Moving files..."))
+ using (ProgressDialog progressDialog = new ProgressDialog(Properties.Resources.ResourceManager.GetString("MovingFilesTitle")))
{
IO.MoveOperation moveOp = IOHelper.MoveDir(source, destination);
@@ -194,7 +254,9 @@ private async Task BeginMove(string source, string destination)
progressDialog.CancelRequested += (sender, e) =>
{
- if (DialogResult.Yes == MessageBox.Show(this, "Are you sure you want to cancel?", "Cancel confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2))
+ string message = Properties.Resources.ResourceManager.GetString("CancelConfirmationMessage");
+ string title = Properties.Resources.ResourceManager.GetString("CancelConfirmationTitle");
+ if (DialogResult.Yes == MessageBox.Show(this, message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2))
{
moveOp.Cancel();
progressDialog.BeginInvoke(new Action(() => progressDialog.Cancellable = false));
@@ -230,9 +292,9 @@ private void SetToolTips()
InitialDelay = 600,
ReshowDelay = 500
};
- Tip.SetToolTip(this.textBox_From, "Select the folder you want to move");
- Tip.SetToolTip(this.textBox_To, "Select where you want to move the folder");
- Tip.SetToolTip(this.chkBox_originalHidden, "Select whether you want to hide the shortcut which is created in the old location or not");
+ Tip.SetToolTip(this.textBox_From, Properties.Resources.ResourceManager.GetString("TooltipFrom"));
+ Tip.SetToolTip(this.textBox_To, Properties.Resources.ResourceManager.GetString("TooltipTo"));
+ Tip.SetToolTip(this.chkBox_originalHidden, Properties.Resources.ResourceManager.GetString("TooltipHidden"));
}
private void Reset()
@@ -244,7 +306,8 @@ private void Reset()
public static void Unauthorized(Exception ex)
{
- MessageBox.Show(Properties.Resources.ErrorUnauthorizedMoveDetails + ex.Message, "Error details");
+ string title = Properties.Resources.ResourceManager.GetString("ErrorDetailsTitle");
+ MessageBox.Show(Properties.Resources.ErrorUnauthorizedMoveDetails + ex.Message, title);
}
#region Event Handlers
@@ -327,12 +390,14 @@ private void CheckOnProgramStartToolStripMenuItem_Click(object sender, EventArgs
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
{
string msg = String.Format(Properties.Resources.AboutContent, System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion);
- MessageBox.Show(msg, "About FreeMove");
+ string title = Properties.Resources.ResourceManager.GetString("AboutTitle");
+ MessageBox.Show(msg, title);
}
private void SafeModeToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (MessageBox.Show(Properties.Resources.DisableSafeModeMessage, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
+ string title = Properties.Resources.ResourceManager.GetString("WarningTitle");
+ if (MessageBox.Show(Properties.Resources.DisableSafeModeMessage, title, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
safeMode = false;
safeModeToolStripMenuItem.Checked = false;
@@ -363,5 +428,32 @@ private void FullToolStripMenuItem_Click(object sender, EventArgs e)
fastToolStripMenuItem.Checked = false;
fullToolStripMenuItem.Checked = true;
}
+
+ private void zhToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // 切换为英文界面
+ Settings.Language = "en";
+ string msg = Properties.Resources.ResourceManager.GetString("LanguageChangedRestartMessage");
+ string title = Properties.Resources.ResourceManager.GetString("LanguageChangedTitle");
+ MessageBox.Show(msg, title);
+ Application.Restart();
+ }
+
+ private void chineseToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // 切换为简体中文界面
+ Settings.Language = "zh-Hans";
+ string msg = Properties.Resources.ResourceManager.GetString("LanguageChangedRestartMessage");
+ string title = Properties.Resources.ResourceManager.GetString("LanguageChangedTitle");
+ MessageBox.Show(msg, title);
+ Application.Restart();
+ }
+
+ private void HelpToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ string help = Properties.Resources.ResourceManager.GetString("HelpContent");
+ string title = Properties.Resources.ResourceManager.GetString("HelpButtonText");
+ MessageBox.Show(this, help, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
}
}
diff --git a/FreeMove/FreeMove.csproj b/FreeMove/FreeMove.csproj
index 4411525..5744d7a 100644
--- a/FreeMove/FreeMove.csproj
+++ b/FreeMove/FreeMove.csproj
@@ -1,6 +1,7 @@
net48
+ 9.0
WinExe
publish\
true
@@ -39,11 +40,14 @@
+
+
+
-
+
diff --git a/FreeMove/Program.cs b/FreeMove/Program.cs
index bfedf00..b3165f1 100644
--- a/FreeMove/Program.cs
+++ b/FreeMove/Program.cs
@@ -19,6 +19,9 @@
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
+using System.Globalization;
+using System.Threading;
+using System.Security.Principal;
namespace FreeMove
{
@@ -30,8 +33,52 @@ static class Program
[STAThread]
static void Main()
{
+ // 如非管理员权限,提示并退出
+ try
+ {
+ using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
+ {
+ WindowsPrincipal principal = new WindowsPrincipal(identity);
+ if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
+ {
+ string msg = Properties.Resources.ResourceManager.GetString("AdminRequiredMessage");
+ string title = Properties.Resources.ResourceManager.GetString("AdminRequiredTitle");
+ MessageBox.Show(msg, title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+ }
+ }
+ catch
+ {
+ // 如果检查失败,出于安全考虑也直接退出
+ string msg = Properties.Resources.ResourceManager.GetString("AdminRequiredMessage");
+ string title = Properties.Resources.ResourceManager.GetString("AdminRequiredTitle");
+ MessageBox.Show(msg, title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+
+ // 设置全局语言:优先使用用户在设置中选择的语言,否则跟随系统
+ try
+ {
+ string lang = Settings.Language;
+ CultureInfo culture;
+ if (!string.IsNullOrEmpty(lang))
+ {
+ culture = new CultureInfo(lang);
+ }
+ else
+ {
+ culture = CultureInfo.InstalledUICulture;
+ }
+ Thread.CurrentThread.CurrentCulture = culture;
+ Thread.CurrentThread.CurrentUICulture = culture;
+ }
+ catch
+ {
+ // 如果设置中的语言代码无效,忽略并使用系统默认
+ }
+
Application.EnableVisualStyles();
- Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
diff --git a/FreeMove/ProgressDialog.cs b/FreeMove/ProgressDialog.cs
index ab2282b..205063b 100644
--- a/FreeMove/ProgressDialog.cs
+++ b/FreeMove/ProgressDialog.cs
@@ -69,7 +69,8 @@ public void UpdateProgress(IO.IOOperation.ProgressChangedEventArgs e)
label_Progress?.BeginInvoke(new Action(() =>
{
float percentage = ((float)e.Progress / e.Max);
- label_Progress.Text = e.Progress == e.Max ? "Finishing..." : $"{e.Progress}/{e.Max}";
+ string finishing = Properties.Resources.ResourceManager.GetString("ProgressFinishingText");
+ label_Progress.Text = e.Progress == e.Max ? finishing : $"{e.Progress}/{e.Max}";
if (e.Progress == e.Max)
Cancellable = false;
// label_Progress.Text = $"{percentage*100f, 3:0.0}%";
diff --git a/FreeMove/Properties/Resources.resx b/FreeMove/Properties/Resources.resx
index f52b321..9e41610 100644
--- a/FreeMove/Properties/Resources.resx
+++ b/FreeMove/Properties/Resources.resx
@@ -183,4 +183,191 @@ If this text file was useful or if you would have preferred it wasn't created le
ImDema-FreeMove-Updater
+
+ Done!
+
+
+ Error
+
+
+ Could not remove copied contents. Try removing manually
+
+
+ Could not move back contents. Try moving manually
+
+
+ Details:
+{0}
+
+
+ Do you want to undo the changes?
+
+Details:
+{0}
+
+
+ Do you want to undo the changes?
+
+
+ Cancelled
+
+
+ Are you sure you want to cancel?
+
+
+ Cancel confirmation
+
+
+ Select the folder you want to move
+
+
+ Select where you want to move the folder
+
+
+ Select whether you want to hide the shortcut which is created in the old location or not
+
+
+ Error details
+
+
+ About FreeMove
+
+
+ Warning
+
+
+ Moving files...
+
+
+ Finishing...
+
+
+ Language has been changed. The application will restart to apply the new language.
+
+
+ Language
+
+
+ Free Move
+
+
+ Move From:
+
+
+ To:
+
+
+ Browse...
+
+
+ Move
+
+
+ Close
+
+
+ Set original folder to hidden
+
+
+ Create destination folder
+
+
+ Settings
+
+
+ Info
+
+
+ Language
+
+
+ Check for update
+
+
+ Check now
+
+
+ Check on program start
+
+
+ Permission check
+
+
+ Safe mode
+
+
+ None
+
+
+ Fast
+
+
+ Full
+
+
+ Report an Issue
+
+
+ GitHub
+
+
+ About
+
+
+ English
+
+
+ Chinese
+
+
+ This application must be run as administrator in order to move folders and create junctions.
+
+Please right-click the executable and choose "Run as administrator".
+
+
+ Administrator required
+
+
+ Help
+
+
+ FreeMove - Help
+
+Move From: Select the folder you want to move (for example, a program folder under Program Files).
+To: Select the target location (for example, another drive) where you want to move the folder.
+Browse... Open a folder picker dialog to choose the source or target folder.
+
+Move: Start moving the selected folder to the target location and create a junction at the original path.
+Close: Close the application window.
+
+Set original folder to hidden:
+ After moving, set the junction at the original location to Hidden so it is not visible in Explorer.
+
+Create destination folder:
+ If checked, FreeMove will create the target folder automatically when needed.
+
+Settings → Check for update:
+ - Check now: Manually check GitHub for a newer version.
+ - Check on program start: If enabled, FreeMove will automatically check for updates when it starts.
+
+Settings → Permission check:
+ - None: Don't check any file before moving (fastest, but may fail later if permissions are missing).
+ - Fast: Check .exe and .dll files before moving (default).
+ - Full: Check all files before moving (slowest, but most thorough).
+
+Settings → Safe mode:
+ Prevents moving critical system folders (such as Program Files). It is strongly recommended to keep this enabled.
+
+Info → Report an Issue:
+ Open the GitHub page to report a bug or request a feature.
+
+Info → GitHub:
+ Open the project page on GitHub.
+
+Info → About:
+ Show information about FreeMove and its license.
+
+Language:
+ - English / Chinese: Switch the user interface language (the application will restart to apply the change).
+
\ No newline at end of file
diff --git a/FreeMove/Properties/Resources.zh-Hans.resx b/FreeMove/Properties/Resources.zh-Hans.resx
new file mode 100644
index 0000000..d8fd074
--- /dev/null
+++ b/FreeMove/Properties/Resources.zh-Hans.resx
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+
+ imDema/FreeMove {0} —— 移动目录而不破坏快捷方式或安装
+版权所有 (C) 2020 Luca De Martini
+
+本程序是自由软件:您可以在 GNU 通用公共许可证(GPL)第 3 版或(由您选择)任何更新版本的条款下重新分发和/或修改本程序。
+
+本程序的发布希望它能带来帮助,但不提供任何担保;甚至不包括适销性或适用于特定目的的默示担保。
+
+您应已随本程序一起收到 GNU 通用公共许可证的副本;如果没有,请参见 <http://www.gnu.org/licenses/>。
+
+https://github.com/imDema
+
+
+
+ 强烈不建议移动 “Program Files” 或 “Program Files (x86)” 目录,否则可能导致系统行为异常。
+推荐只移动这些目录中的具体程序文件夹。
+
+确定要关闭安全模式吗?
+
+
+
+ 创建符号链接时出错。
+文件夹已经移动到新位置,但无法创建链接。
+请尝试以管理员身份运行程序。
+
+要把文件移回原位置吗?
+
+
+
+ 移动文件时发生错误,某些文件可能正在被占用,或者您没有足够的权限。
+
+请尝试以管理员身份运行本程序,并关闭正在使用该文件的其他程序。
+
+详细信息:
+
+
+
+ 错误:{0}
+
+如何继续?
+“中止” 将撤销更改
+“忽略” 将停止程序
+
+
+
+ 无法从 GitHub 服务器获取版本信息
+
+
+
+ 确定要继续吗?
+
+如果选择忽略,文件将保持当前状态:部分文件已经在新位置,且在旧位置中缺失!
+
+
+
+ 在 {0} 使用 FreeMove 移动文件时发生错误,并且您选择了“忽略”。
+此目录的其余内容可在 “{1}” 中找到(除非已经被再次移动)。
+下次在发生错误时,请使用 “中止” 将文件移回,或使用 “重试” 再试一次。
+
+如果这个文本文件对您有帮助,或者您希望它不要被创建,请告诉我。
+
+
+
+ ImDema-FreeMove-Updater
+
+
+
+
+
+ 完成!
+
+
+
+ 错误
+
+
+
+ 无法删除已复制的内容,请尝试手动删除。
+
+
+
+ 无法将内容移回原位置,请尝试手动移动。
+
+
+
+ 详细信息:
+{0}
+
+
+
+ 要撤销这些更改吗?
+
+详细信息:
+{0}
+
+
+
+ 要撤销这些更改吗?
+
+
+
+ 已取消
+
+
+
+ 确定要取消正在进行的操作吗?
+
+
+
+ 取消确认
+
+
+
+ 选择要移动的文件夹
+
+
+
+ 选择目标位置
+
+
+
+ 选择是否隐藏在原位置创建的快捷方式(链接)
+
+
+
+ 错误详情
+
+
+
+ 关于 FreeMove
+
+
+
+ 警告
+
+
+
+ 正在移动文件...
+
+
+
+ 正在完成...
+
+
+
+ 语言已更改,程序将重新启动以应用新的语言设置。
+
+
+
+ 语言
+
+
+
+ Free Move
+
+
+
+ 源文件夹:
+
+
+
+ 目标位置:
+
+
+
+ 浏览...
+
+
+
+ 开始移动
+
+
+
+ 关闭
+
+
+
+ 将原位置的文件夹设为隐藏
+
+
+
+ 自动创建目标文件夹
+
+
+
+ 设置
+
+
+
+ 信息
+
+
+
+ 语言
+
+
+
+ 检查更新
+
+
+
+ 立即检查
+
+
+
+ 启动时检查
+
+
+
+ 权限检查
+
+
+
+ 安全模式
+
+
+
+ 不检查
+
+
+
+ 快速
+
+
+
+ 完全
+
+
+
+ 反馈问题
+
+
+
+ GitHub
+
+
+
+ 关于
+
+
+
+ 英文
+
+
+
+ 简体中文
+
+
+
+ 本程序需要以管理员身份运行才能移动文件夹并创建链接。
+
+请右键单击可执行文件,选择“以管理员身份运行”。
+
+
+
+ 需要管理员权限
+
+
+
+ 帮助
+
+
+
+ FreeMove 使用说明
+
+源文件夹: 选择你要移动的文件夹(例如 Program Files 下的某个程序目录)。
+目标位置: 选择要把该文件夹移动到的目标路径(例如另一块磁盘)。
+浏览...: 打开文件夹选择对话框,用来选择源或目标文件夹。
+
+开始移动: 开始将所选文件夹移动到目标位置,并在原路径创建一个目录链接(junction)。
+关闭: 关闭程序窗口。
+
+将原位置的文件夹设为隐藏:
+ 移动完成后,把原位置创建的链接设为“隐藏”,在资源管理器中不明显显示。
+
+自动创建目标文件夹:
+ 如果勾选,在需要时自动创建目标文件夹。
+
+设置 → 检查更新:
+ - 立即检查: 立刻连接 GitHub 检查是否有新版本。
+ - 启动时检查: 每次启动 FreeMove 时自动检查是否有新版本。
+
+设置 → 权限检查:
+ - 不检查: 不预先检查任何文件权限(速度最快,但可能在后面操作时才失败)。
+ - 快速: 只预检查 .exe 和 .dll 文件的权限(默认)。
+ - 完全: 预检查所有文件的权限(最慢,但最安全)。
+
+设置 → 安全模式:
+ 阻止移动关键系统目录(例如 Program Files)。强烈建议保持开启。
+
+信息 → 反馈问题:
+ 打开 GitHub 的 Issue 页面,用于反馈 Bug 或提出建议。
+
+信息 → GitHub:
+ 打开本项目的 GitHub 主页。
+
+信息 → 关于:
+ 显示 FreeMove 的版本和授权信息。
+
+语言:
+ - 英文 / 简体中文:切换界面语言(程序将重启以应用新的语言)。
+
+
+
+
diff --git a/FreeMove/Properties/Settings.Designer.cs b/FreeMove/Properties/Settings.Designer.cs
index 84c6380..f2f2af5 100644
--- a/FreeMove/Properties/Settings.Designer.cs
+++ b/FreeMove/Properties/Settings.Designer.cs
@@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.42000
//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
//
//------------------------------------------------------------------------------
@@ -12,7 +12,7 @@ namespace FreeMove.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.1.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/FreeMove/Settings.cs b/FreeMove/Settings.cs
index 9f2cb54..bf32b33 100644
--- a/FreeMove/Settings.cs
+++ b/FreeMove/Settings.cs
@@ -39,6 +39,9 @@ public enum PermissionCheckLevel
public PermissionCheckLevel PermissionCheck = PermissionCheckLevel.Fast;
+ // UI language code, e.g. "en", "zh-Hans". null/empty = follow system language
+ public string LanguageCode = null;
+
public static bool AutoUpdate
{
set
@@ -69,6 +72,21 @@ public static PermissionCheckLevel PermCheck
}
}
+ public static string Language
+ {
+ get
+ {
+ var LSett = Load();
+ return LSett.LanguageCode;
+ }
+ set
+ {
+ var LSett = Load();
+ LSett.LanguageCode = value;
+ Save(LSett);
+ }
+ }
+
private static void Save(Settings set)
{
XmlSerializer ser = new XmlSerializer(typeof(Settings));
@@ -86,10 +104,27 @@ private static Settings Load()
if (File.Exists(GetSavePath()))
{
- using (FileStream fs = File.OpenRead(GetSavePath()))
+ try
+ {
+ using (FileStream fs = File.OpenRead(GetSavePath()))
+ {
+ XmlSerializer ser = new XmlSerializer(typeof(Settings));
+ LoadedSettings = ser.Deserialize(fs) as Settings;
+ }
+ }
+ catch (InvalidOperationException)
{
- XmlSerializer ser = new XmlSerializer(typeof(Settings));
- LoadedSettings = ser.Deserialize(fs) as Settings;
+ // 配置文件格式与当前 Settings 不兼容(例如旧版本保存为 bool 的值现在改成了枚举)
+ // 删除损坏/旧格式配置文件,回退到默认设置
+ try
+ {
+ File.Delete(GetSavePath());
+ }
+ catch
+ {
+ // 忽略删除失败,使用默认设置继续运行
+ }
+ LoadedSettings = null;
}
}