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