Skip to content

Commit 5f4fa1f

Browse files
Merge pull request #13 from andreaskueffel/development
Development
2 parents f3aa3c1 + e2df39b commit 5f4fa1f

4 files changed

Lines changed: 160 additions & 7 deletions

File tree

FileSyncAppWin/Program.cs

Lines changed: 152 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,164 @@
1+
using Microsoft.Extensions.Logging;
2+
using System.IO.Pipes;
3+
14
namespace FileSyncAppWin
25
{
36
internal static class Program
47
{
8+
9+
private static Mutex mutex = new Mutex(true, "PraewemaFileSyncAppWin");
10+
private static volatile bool autoRestart = true;
11+
private static ILogger logger;
12+
private static Form mainForm;
13+
private const string PipeName = "PraewemaFileSyncAppWinPipe";
14+
515
/// <summary>
616
/// The main entry point for the application.
717
/// </summary>
818
[STAThread]
9-
static void Main()
19+
static void Main(string[] args)
1020
{
11-
// To customize application configuration such as set high DPI settings or default font,
12-
// see https://aka.ms/applicationconfiguration.
13-
ApplicationConfiguration.Initialize();
14-
Application.Run(new MainForm());
21+
FileSyncApp.Program.ConfigureLogger();
22+
logger = FileSyncApp.Program.LoggerFactory.CreateLogger("FileSyncAppWin");
23+
if (args.Contains("noautorestart"))
24+
{
25+
logger?.LogInformation("startup argument noautorestart given, settings autoRestart to false");
26+
autoRestart = false;
27+
}
28+
if (args.Contains("restart"))
29+
{
30+
logger?.LogInformation("startup argument restart given, sending exit signal to running instance");
31+
SendExitSignalToFirstInstance();
32+
}
33+
logger?.LogInformation("try to get mutex");
34+
// Try to acquire the mutex
35+
if (!mutex.WaitOne(TimeSpan.FromSeconds(15)))
36+
{
37+
// Mutex was not acquired, meaning another instance is running
38+
39+
Console.WriteLine("FileSyncAppWin another instance is running, exiting.");
40+
logger?.LogInformation("FileSyncAppWin another instance is running, exiting.");
41+
return; // Exit the second instance
42+
}
43+
44+
try
45+
{
46+
var pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.InOut);
47+
// Start listening for incoming connections
48+
pipeServer.BeginWaitForConnection(PipeConnectedCallback, pipeServer);
49+
50+
logger?.LogInformation("FileSyncAppWin Main program starting...");
51+
Application.ThreadException += Application_ThreadException;
52+
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
53+
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
54+
ApplicationConfiguration.Initialize();
55+
mainForm = new MainForm();
56+
Application.Run(mainForm);
57+
}
58+
catch (Exception exception)
59+
{
60+
logger?.LogError(exception, "FileSyncAppWin exception in main logic");
61+
}
62+
finally
63+
{
64+
logger?.LogInformation("FileSyncAppWin releasing mutex");
65+
mutex.ReleaseMutex();
66+
}
67+
68+
}
69+
70+
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
71+
{
72+
try
73+
{
74+
logger?.LogCritical((Exception)e.ExceptionObject, "CurrentDomain_UnhandledException isTerminating {A}", e.IsTerminating);
75+
}
76+
catch (Exception castException)
77+
{
78+
logger?.LogCritical(castException, "CurrentDomain_UnhandledException, Exception object {@A}", e.ExceptionObject);
79+
}
80+
//if (e.IsTerminating)
81+
{
82+
RestartApplication();
83+
}
84+
85+
}
86+
87+
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
88+
{
89+
logger?.LogCritical(e.Exception, "Application_ThreadException");
90+
RestartApplication();
91+
}
92+
93+
private static void PipeConnectedCallback(IAsyncResult result)
94+
{
95+
var pipeServer = (NamedPipeServerStream)result.AsyncState;
96+
97+
try
98+
{
99+
// End waiting for the connection
100+
pipeServer.EndWaitForConnection(result);
101+
102+
// Read the message from the pipe
103+
using (var reader = new StreamReader(pipeServer))
104+
{
105+
string message = reader.ReadLine();
106+
if (message == "Exit")
107+
{
108+
logger?.LogInformation("Received exit signal from second instance. Exiting gracefully.");
109+
mainForm.Close();
110+
//Environment.Exit(0); // Gracefully exit the application
111+
}
112+
}
113+
114+
// Close the pipe
115+
pipeServer.Close();
116+
}
117+
catch (Exception ex)
118+
{
119+
logger?.LogError(ex, "Error handling named pipe connection.");
120+
}
121+
}
122+
123+
private static void SendExitSignalToFirstInstance()
124+
{
125+
try
126+
{
127+
using (var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
128+
{
129+
pipeClient.Connect(500); // Connect with a timeout
130+
131+
// Send an exit signal
132+
using (var writer = new StreamWriter(pipeClient))
133+
{
134+
writer.WriteLine("Exit");
135+
}
136+
}
137+
}
138+
catch (Exception ex)
139+
{
140+
logger?.LogError(ex, "Error sending exit signal to first instance.");
141+
}
142+
}
143+
144+
145+
private static void RestartApplication()
146+
{
147+
if (autoRestart)
148+
{
149+
// Get the path of the current application
150+
string assemblyPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
151+
// Restart the application using the path
152+
logger?.LogInformation("RestartApplication, starting new process {A}", assemblyPath);
153+
System.Diagnostics.Process.Start(assemblyPath);
154+
155+
// Exit the current instance of the application
156+
Environment.Exit(0);
157+
}
158+
else
159+
{
160+
logger?.LogInformation("RestartApplication, skip starting new process -> autoRestart=false");
161+
}
15162
}
16163
}
17164
}

FileSyncLibNet/FileCleanJob/FileCleanJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static IFileJob CreateJob(IFileCleanJobOptions fileCleanJobOptions)
3131
// try
3232
// {
3333
// Dictionary<string, int> pathMaxDays = new Dictionary<string, int>();
34-
// string[] subFolders = { "HriFFTLog", "HriShockLog", "HriLog", "HriDebugLog", "raw" };
34+
//
3535
// var driveInfo = new DriveInfo(Hauptprogramms.First().ProductionDataPath);
3636
// int days = 59;
3737

FileSyncLibNet/FileSyncJob/FileSyncJobOptionsBuilder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public IFileSyncJobOptionsBuilderSetProperties WithSubfolder(string subfolder)
8181
jobOptions.Subfolders.Add(subfolder);
8282
return this;
8383
}
84+
public IFileSyncJobOptionsBuilderSetProperties WithSubfolders(params string[] subfolders)
85+
{
86+
jobOptions.Subfolders.AddRange(subfolders);
87+
return this;
88+
}
8489
public IFileSyncJobOptionsBuilderSetProperties DeleteAfterBackup(bool deleteAfterBackup)
8590
{
8691
jobOptions.DeleteSourceAfterBackup = deleteAfterBackup;
@@ -136,6 +141,7 @@ public interface IFileSyncJobOptionsBuilderSetProperties : IFileSyncJobOptionsBu
136141
IFileSyncJobOptionsBuilderSetProperties WithCredentials(NetworkCredential networkCredential);
137142
IFileSyncJobOptionsBuilderSetProperties WithSearchPattern(string searchPattern);
138143
IFileSyncJobOptionsBuilderSetProperties WithSubfolder(string subfolder);
144+
IFileSyncJobOptionsBuilderSetProperties WithSubfolders(params string[] subfolders);
139145
IFileSyncJobOptionsBuilderSetProperties DeleteAfterBackup(bool deleteAfterBackup);
140146
IFileSyncJobOptionsBuilderSetProperties WithLogger(ILogger logger);
141147
IFileSyncJobOptionsBuilderSetProperties WithLogger(Action<string> loggerAction);

FileSyncLibNet/SyncProviders/FileIOProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ void EnsureAccess()
240240
// catch { log.LogInformation($"Konnte nicht auf Backuppfad {backupTarget} schreiben"); canWrite = false; }
241241
// }
242242
// if (canWrite)
243-
// foreach (string folder in new string[] { "HriFFTLog", "HriShockLog", "HriLog", "HriDebugLog", "HRI" })
243+
//
244244
// {
245245
// string _path = Path.Combine(ProductionDataPath, folder);
246246
// if (!Directory.Exists(_path))

0 commit comments

Comments
 (0)