diff --git a/FileSyncApp/FileSyncApp.csproj b/FileSyncApp/FileSyncApp.csproj
index 3b50487..0ef6a67 100644
--- a/FileSyncApp/FileSyncApp.csproj
+++ b/FileSyncApp/FileSyncApp.csproj
@@ -2,13 +2,13 @@
Exe
- net6.0
+ net8.0
-
-
+
+
diff --git a/FileSyncApp/Program.cs b/FileSyncApp/Program.cs
index ab27a16..b9a5ec8 100644
--- a/FileSyncApp/Program.cs
+++ b/FileSyncApp/Program.cs
@@ -129,6 +129,11 @@ static void RunProgram()
{
Thread.Sleep(500);
}
+ foreach(var job in Jobs)
+ {
+ job.Value.StopJob();
+ }
+ Jobs.Clear();
}
diff --git a/FileSyncAppConfigEditor/FileSyncAppConfigEditor.csproj b/FileSyncAppConfigEditor/FileSyncAppConfigEditor.csproj
new file mode 100644
index 0000000..5c8aafa
--- /dev/null
+++ b/FileSyncAppConfigEditor/FileSyncAppConfigEditor.csproj
@@ -0,0 +1,25 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ true
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/FileSyncAppConfigEditor/IgnorePropertyResolver.cs b/FileSyncAppConfigEditor/IgnorePropertyResolver.cs
new file mode 100644
index 0000000..b6aea31
--- /dev/null
+++ b/FileSyncAppConfigEditor/IgnorePropertyResolver.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace FileSyncAppConfigEditor
+{
+ //short helper class to ignore some properties from serialization
+ public class IgnorePropertyResolver: DefaultContractResolver
+ {
+ private readonly HashSet ignoreProps;
+ public IgnorePropertyResolver(params string[] propNamesToIgnore)
+ {
+ this.ignoreProps = new HashSet(propNamesToIgnore);
+ }
+
+ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+ {
+ JsonProperty property = base.CreateProperty(member, memberSerialization);
+ if (this.ignoreProps.Contains(property.PropertyName))
+ {
+ property.ShouldSerialize = _ => false;
+ }
+ return property;
+ }
+ }
+}
+
diff --git a/FileSyncAppConfigEditor/JobsEditForm.Designer.cs b/FileSyncAppConfigEditor/JobsEditForm.Designer.cs
new file mode 100644
index 0000000..e13e6d1
--- /dev/null
+++ b/FileSyncAppConfigEditor/JobsEditForm.Designer.cs
@@ -0,0 +1,166 @@
+namespace FileSyncAppConfigEditor
+{
+ partial class JobsEditForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ pg_JobEdit = new PropertyGrid();
+ lb_Jobs = new ListBox();
+ btn_Add = new Button();
+ btn_Remove = new Button();
+ btn_Save = new Button();
+ btn_Load = new Button();
+ openFileDialog1 = new OpenFileDialog();
+ tb_JobName = new TextBox();
+ btn_Rename = new Button();
+ btn_AddCleanJob = new Button();
+ saveFileDialog1 = new SaveFileDialog();
+ SuspendLayout();
+ //
+ // pg_JobEdit
+ //
+ pg_JobEdit.Location = new Point(270, 12);
+ pg_JobEdit.Name = "pg_JobEdit";
+ pg_JobEdit.Size = new Size(518, 426);
+ pg_JobEdit.TabIndex = 0;
+ //
+ // lb_Jobs
+ //
+ lb_Jobs.FormattingEnabled = true;
+ lb_Jobs.ItemHeight = 15;
+ lb_Jobs.Location = new Point(12, 12);
+ lb_Jobs.Name = "lb_Jobs";
+ lb_Jobs.Size = new Size(252, 319);
+ lb_Jobs.TabIndex = 1;
+ lb_Jobs.SelectedIndexChanged += ListBoxJobs_SelectedIndexChanged;
+ //
+ // btn_Add
+ //
+ btn_Add.Location = new Point(12, 382);
+ btn_Add.Name = "btn_Add";
+ btn_Add.Size = new Size(75, 23);
+ btn_Add.TabIndex = 2;
+ btn_Add.Text = "Add Sync Job";
+ btn_Add.UseVisualStyleBackColor = true;
+ btn_Add.Click += ButtonAddJob_Click;
+ //
+ // btn_Remove
+ //
+ btn_Remove.Location = new Point(189, 382);
+ btn_Remove.Name = "btn_Remove";
+ btn_Remove.Size = new Size(75, 23);
+ btn_Remove.TabIndex = 3;
+ btn_Remove.Text = "Remove";
+ btn_Remove.UseVisualStyleBackColor = true;
+ btn_Remove.Click += ButtonRemoveJob_Click;
+ //
+ // btn_Save
+ //
+ btn_Save.Location = new Point(189, 415);
+ btn_Save.Name = "btn_Save";
+ btn_Save.Size = new Size(75, 23);
+ btn_Save.TabIndex = 4;
+ btn_Save.Text = "Save";
+ btn_Save.UseVisualStyleBackColor = true;
+ btn_Save.Click += ButtonSaveConfig_Click;
+ //
+ // btn_Load
+ //
+ btn_Load.Location = new Point(108, 415);
+ btn_Load.Name = "btn_Load";
+ btn_Load.Size = new Size(75, 23);
+ btn_Load.TabIndex = 5;
+ btn_Load.Text = "Load";
+ btn_Load.UseVisualStyleBackColor = true;
+ btn_Load.Click += ButtonLoadJobs_Click;
+ //
+ // openFileDialog1
+ //
+ openFileDialog1.FileName = "openFileDialog1";
+ //
+ // tb_JobName
+ //
+ tb_JobName.Location = new Point(12, 338);
+ tb_JobName.Name = "tb_JobName";
+ tb_JobName.Size = new Size(171, 23);
+ tb_JobName.TabIndex = 6;
+ //
+ // btn_Rename
+ //
+ btn_Rename.Location = new Point(189, 337);
+ btn_Rename.Name = "btn_Rename";
+ btn_Rename.Size = new Size(75, 23);
+ btn_Rename.TabIndex = 7;
+ btn_Rename.Text = "Rename";
+ btn_Rename.UseVisualStyleBackColor = true;
+ btn_Rename.Click += ButtonRenameJob_Click;
+ //
+ // btn_AddCleanJob
+ //
+ btn_AddCleanJob.Location = new Point(93, 382);
+ btn_AddCleanJob.Name = "btn_AddCleanJob";
+ btn_AddCleanJob.Size = new Size(75, 23);
+ btn_AddCleanJob.TabIndex = 8;
+ btn_AddCleanJob.Text = "Add Clean Job";
+ btn_AddCleanJob.UseVisualStyleBackColor = true;
+ btn_AddCleanJob.Click += ButtonAddJob_Click;
+ //
+ // JobsEditForm
+ //
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(800, 450);
+ Controls.Add(btn_AddCleanJob);
+ Controls.Add(btn_Rename);
+ Controls.Add(tb_JobName);
+ Controls.Add(btn_Load);
+ Controls.Add(btn_Save);
+ Controls.Add(btn_Remove);
+ Controls.Add(btn_Add);
+ Controls.Add(lb_Jobs);
+ Controls.Add(pg_JobEdit);
+ Name = "JobsEditForm";
+ Text = "JobsEditForm";
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private PropertyGrid pg_JobEdit;
+ private ListBox lb_Jobs;
+ private Button btn_Add;
+ private Button btn_Remove;
+ private Button btn_Save;
+ private Button btn_Load;
+ private OpenFileDialog openFileDialog1;
+ private TextBox tb_JobName;
+ private Button btn_Rename;
+ private Button btn_AddCleanJob;
+ private SaveFileDialog saveFileDialog1;
+ }
+}
diff --git a/FileSyncAppConfigEditor/JobsEditForm.cs b/FileSyncAppConfigEditor/JobsEditForm.cs
new file mode 100644
index 0000000..36a167e
--- /dev/null
+++ b/FileSyncAppConfigEditor/JobsEditForm.cs
@@ -0,0 +1,186 @@
+using FileSyncLibNet.Commons;
+using FileSyncLibNet.FileCleanJob;
+using FileSyncLibNet.FileSyncJob;
+using Newtonsoft.Json;
+using RoboSharp.Interfaces;
+using System.Text.Json;
+
+namespace FileSyncAppConfigEditor
+{
+ public partial class JobsEditForm : Form
+ {
+ private string configFilePath = "config.json";
+ private Dictionary jobs;
+ JsonSerializerSettings jsonSettings;
+
+ public JobsEditForm(string initialFile=null)
+ {
+ InitializeComponent();
+ Init();
+ if(!string.IsNullOrEmpty(initialFile) && File.Exists(initialFile))
+ {
+ configFilePath = initialFile;
+ LoadJobsFromFile(initialFile);
+ }
+ }
+
+ void Init()
+ {
+ jsonSettings = new JsonSerializerSettings
+ {
+ ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+ ContractResolver = new IgnorePropertyResolver(new string[] { "Logger" }),
+ TypeNameHandling = TypeNameHandling.Auto,
+ Formatting = Formatting.Indented
+ };
+ openFileDialog1.FileName = configFilePath;
+ saveFileDialog1.FileName = configFilePath;
+ pg_JobEdit.SelectedGridItemChanged += (s, ev) =>
+ {
+ if (ev.NewSelection != null)
+ {
+ //var prop = ev.NewSelection.PropertyDescriptor;
+ //if (prop != null)
+ //{
+ // var propValue = prop.GetValue(jobs[selectedJob]);
+ // if (propValue != null)
+ // {
+ // if (prop.PropertyType == typeof(System.Net.NetworkCredential))
+ // {
+ // var cred = propValue as System.Net.NetworkCredential;
+ // if (cred != null)
+ // {
+ // cred.Password = "";
+ // }
+ // }
+ // }
+ //}
+ }
+ };
+ }
+
+ private void ButtonLoadJobs_Click(object sender, EventArgs e)
+ {
+ openFileDialog1.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*";
+ var result = openFileDialog1.ShowDialog();
+ if (result != DialogResult.OK)
+ return;
+ configFilePath = openFileDialog1.FileName;
+ if (File.Exists(configFilePath))
+ {
+ LoadJobsFromFile(configFilePath);
+ }
+ else
+ {
+ jobs = new Dictionary();
+ }
+ }
+
+ private void LoadJobsFromFile(string configFilePath)
+ {
+ string json = File.ReadAllText(configFilePath);
+ jobs = JsonConvert.DeserializeObject>(json, jsonSettings);
+ lb_Jobs.Items.Clear();
+ foreach (var job in jobs.Keys)
+ {
+ lb_Jobs.Items.Add(job);
+ }
+ }
+
+ private void ListBoxJobs_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (lb_Jobs.SelectedItem != null)
+ {
+ string selectedJob = lb_Jobs.SelectedItem.ToString();
+ pg_JobEdit.SelectedObject = jobs[selectedJob];
+
+ tb_JobName.Text = selectedJob; // Set the text box to the selected job name
+ }
+ }
+
+ private void ButtonAddJob_Click(object sender, EventArgs e)
+ {
+ string newJobName = "NewJob_" + DateTime.Now.Ticks;
+ IFileJobOptions newJob = null;
+ if (sender == btn_Add)
+ {
+ newJob = new FileSyncJobOptions()
+ {
+ SourcePath = "C:\\Source",
+ SyncDeleted = false,
+ DeleteSourceAfterBackup = false,
+ RememberLastSync = true,
+ MaxAge = TimeSpan.FromDays(10),
+ Credentials = new System.Net.NetworkCredential { UserName = "", Password = "", Domain = "" },
+ DestinationPath = "D:\\Destination",
+ Interval = TimeSpan.FromMinutes(5),
+ SearchPattern = "*.*",
+ Subfolders = new List(),
+ Recursive = true,
+ FileSyncProvider = FileSyncLibNet.SyncProviders.SyncProvider.Abstract
+ };
+ }
+ if (sender == btn_AddCleanJob)
+ {
+ newJob = new FileCleanJobOptions()
+ {
+ DestinationPath = "C:\\temp",
+ Credentials = new System.Net.NetworkCredential { UserName = "", Password = "", Domain = "" },
+ MaxAge = TimeSpan.FromDays(10),
+ Interval = TimeSpan.FromMinutes(5),
+ FileSyncProvider = FileSyncLibNet.SyncProviders.SyncProvider.Abstract
+ };
+ }
+
+ jobs.Add(newJobName, newJob);
+ lb_Jobs.Items.Add(newJobName);
+ }
+
+ private void ButtonRemoveJob_Click(object sender, EventArgs e)
+ {
+ if (lb_Jobs.SelectedItem != null)
+ {
+ string selectedJob = lb_Jobs.SelectedItem.ToString();
+ jobs.Remove(selectedJob);
+ lb_Jobs.Items.Remove(selectedJob);
+ pg_JobEdit.SelectedObject = null;
+ tb_JobName.Text = ""; // Clear the text box
+ }
+ }
+
+ private void ButtonSaveConfig_Click(object sender, EventArgs e)
+ {
+ saveFileDialog1.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*";
+ var result = saveFileDialog1.ShowDialog();
+ if (result != DialogResult.OK)
+ return;
+ configFilePath = saveFileDialog1.FileName;
+ string json = JsonConvert.SerializeObject(jobs, jsonSettings);
+ File.WriteAllText(configFilePath, json);
+ MessageBox.Show("Configuration saved successfully.", "Save Config", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+
+ private void ButtonRenameJob_Click(object sender, EventArgs e)
+ {
+ if (lb_Jobs.SelectedItem != null && !string.IsNullOrWhiteSpace(tb_JobName.Text))
+ {
+ string oldJobName = lb_Jobs.SelectedItem.ToString();
+ string newJobName = tb_JobName.Text;
+
+ if (jobs.ContainsKey(newJobName))
+ {
+ MessageBox.Show("A job with this name already exists.", "Rename Job", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+
+ var job = jobs[oldJobName];
+ jobs.Remove(oldJobName);
+ jobs.Add(newJobName, job);
+
+ int selectedIndex = lb_Jobs.SelectedIndex;
+ lb_Jobs.Items[selectedIndex] = newJobName;
+ lb_Jobs.SelectedIndex = selectedIndex;
+ }
+ }
+ }
+}
diff --git a/FileSyncAppConfigEditor/JobsEditForm.resx b/FileSyncAppConfigEditor/JobsEditForm.resx
new file mode 100644
index 0000000..9e0824f
--- /dev/null
+++ b/FileSyncAppConfigEditor/JobsEditForm.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
+ 156, 17
+
+
\ No newline at end of file
diff --git a/FileSyncAppConfigEditor/Program.cs b/FileSyncAppConfigEditor/Program.cs
new file mode 100644
index 0000000..e91d8bd
--- /dev/null
+++ b/FileSyncAppConfigEditor/Program.cs
@@ -0,0 +1,17 @@
+namespace FileSyncAppConfigEditor
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new JobsEditForm());
+ }
+ }
+}
\ No newline at end of file
diff --git a/FileSyncAppWin/FileSyncAppWin.csproj b/FileSyncAppWin/FileSyncAppWin.csproj
index aedd9ba..82030c1 100644
--- a/FileSyncAppWin/FileSyncAppWin.csproj
+++ b/FileSyncAppWin/FileSyncAppWin.csproj
@@ -2,13 +2,14 @@
WinExe
- net6.0-windows
+ net8.0-windows
true
enable
+
diff --git a/FileSyncAppWin/MainForm.Designer.cs b/FileSyncAppWin/MainForm.Designer.cs
index d4a7921..1a061e9 100644
--- a/FileSyncAppWin/MainForm.Designer.cs
+++ b/FileSyncAppWin/MainForm.Designer.cs
@@ -32,6 +32,10 @@ private void InitializeComponent()
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
textBox1 = new TextBox();
notifyIcon1 = new NotifyIcon(components);
+ panel1 = new Panel();
+ btn_Config = new Button();
+ btn_Restart = new Button();
+ panel1.SuspendLayout();
SuspendLayout();
//
// textBox1
@@ -42,7 +46,7 @@ private void InitializeComponent()
textBox1.Name = "textBox1";
textBox1.ReadOnly = true;
textBox1.ScrollBars = ScrollBars.Vertical;
- textBox1.Size = new Size(800, 450);
+ textBox1.Size = new Size(732, 299);
textBox1.TabIndex = 0;
//
// notifyIcon1
@@ -50,21 +54,58 @@ private void InitializeComponent()
notifyIcon1.Icon = (Icon)resources.GetObject("notifyIcon1.Icon");
notifyIcon1.Text = "FileSyncAppWin";
//
+ // panel1
+ //
+ panel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
+ panel1.Controls.Add(textBox1);
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(732, 299);
+ panel1.TabIndex = 1;
+ //
+ // btn_Config
+ //
+ btn_Config.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ btn_Config.Location = new Point(562, 326);
+ btn_Config.Name = "btn_Config";
+ btn_Config.Size = new Size(75, 23);
+ btn_Config.TabIndex = 2;
+ btn_Config.Text = "Config";
+ btn_Config.UseVisualStyleBackColor = true;
+ btn_Config.Click += btn_Config_Click;
+ //
+ // btn_Restart
+ //
+ btn_Restart.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ btn_Restart.Location = new Point(647, 326);
+ btn_Restart.Name = "btn_Restart";
+ btn_Restart.Size = new Size(75, 23);
+ btn_Restart.TabIndex = 3;
+ btn_Restart.Text = "Restart";
+ btn_Restart.UseVisualStyleBackColor = true;
+ btn_Restart.Click += btn_Restart_Click;
+ //
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
- ClientSize = new Size(800, 450);
- Controls.Add(textBox1);
+ ClientSize = new Size(734, 361);
+ Controls.Add(btn_Restart);
+ Controls.Add(btn_Config);
+ Controls.Add(panel1);
Name = "MainForm";
Text = "FileSyncAppWin";
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
ResumeLayout(false);
- PerformLayout();
}
#endregion
private TextBox textBox1;
private NotifyIcon notifyIcon1;
+ private Panel panel1;
+ private Button btn_Config;
+ private Button btn_Restart;
}
}
\ No newline at end of file
diff --git a/FileSyncAppWin/MainForm.cs b/FileSyncAppWin/MainForm.cs
index faec8ca..fbbf3b5 100644
--- a/FileSyncAppWin/MainForm.cs
+++ b/FileSyncAppWin/MainForm.cs
@@ -3,15 +3,20 @@ namespace FileSyncAppWin
public partial class MainForm : Form
{
Thread consoleThread;
+ string[] Args;
public MainForm(string[] args)
{
InitializeComponent();
- this.FormClosing += (s, e) => { FileSyncApp.Program.keepRunning = false; consoleThread?.Join(10_000); };
- consoleThread = new Thread(() =>
- {
- FileSyncApp.Program.Main(args);
- });
+ Args = args;
+ this.FormClosing += (s, e) => {
+ NewLogOutput($"FormClosing, Reason {e.CloseReason}");
+ FileSyncApp.Program.keepRunning = false;
+ Program.autoRestart = false;
+ consoleThread?.Join(10_000);
+ NewLogOutput($"FormClosing, Reason {e.CloseReason}, consoleThread joined");
+ };
+
FileSyncApp.Program.JobsReady += (s, e) =>
{
foreach (var job in FileSyncApp.Program.Jobs)
@@ -33,8 +38,7 @@ public MainForm(string[] args)
};
- consoleThread.Start();
-
+
this.Resize += ((s, e) =>
{
this.SuspendLayout();
@@ -57,11 +61,26 @@ public MainForm(string[] args)
};
notifyIcon1.BalloonTipClicked += (s, e) => { this.BeginInvoke(() => { WindowState = FormWindowState.Normal; ShowInTaskbar = true; }); };
//notifyIcon1.BalloonTipShown += (s, e) => { ShowInTaskbar = false; };
-
+ StartConsoleThread();
//this.WindowState = FormWindowState.Minimized;
}
+ void StartConsoleThread()
+ {
+ consoleThread = new Thread(() =>
+ {
+ FileSyncApp.Program.Main(Args);
+ });
+ consoleThread.Start();
+ }
+ void Restart()
+ {
+ FileSyncApp.Program.keepRunning = false;
+ consoleThread?.Join(10_000);
+ FileSyncApp.Program.keepRunning = true;
+ StartConsoleThread();
+ }
private void NewLogOutput(string e)
@@ -70,5 +89,16 @@ private void NewLogOutput(string e)
this.BeginInvoke(() => { textBox1.Text = string.Join(Environment.NewLine, (new string[] { $"{DateTime.Now.ToString("HH:mm:ss.fff")} {e}" }).Concat(textBox1.Text.Split(Environment.NewLine).Take(1000))); });
}
+
+ private void btn_Config_Click(object sender, EventArgs e)
+ {
+ FileSyncAppConfigEditor.JobsEditForm jobsEditForm = new FileSyncAppConfigEditor.JobsEditForm("config.json");
+ jobsEditForm.ShowDialog();
+ }
+
+ private void btn_Restart_Click(object sender, EventArgs e)
+ {
+ Restart();
+ }
}
}
\ No newline at end of file
diff --git a/FileSyncAppWin/MainForm.resx b/FileSyncAppWin/MainForm.resx
index 692f1df..e46894b 100644
--- a/FileSyncAppWin/MainForm.resx
+++ b/FileSyncAppWin/MainForm.resx
@@ -1,7 +1,7 @@