2017-05-18 11:06:18 +02:00
|
|
|
|
|
|
|
|
|
using Acacia;
|
2017-09-06 08:32:09 +02:00
|
|
|
|
using Acacia.Utils;
|
|
|
|
|
using Microsoft.Win32;
|
2017-05-18 11:06:18 +02:00
|
|
|
|
/// Copyright 2017 Kopano b.v.
|
2017-02-15 12:01:04 +01:00
|
|
|
|
///
|
|
|
|
|
/// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
/// it under the terms of the GNU Affero General Public License, version 3,
|
|
|
|
|
/// as published by the Free Software Foundation.
|
|
|
|
|
///
|
|
|
|
|
/// This program is distributed in the hope that it will be useful,
|
|
|
|
|
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
|
|
|
|
/// GNU Affero General Public License for more details.
|
|
|
|
|
///
|
|
|
|
|
/// You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
|
|
|
|
|
///
|
|
|
|
|
/// Consult LICENSE file for details
|
|
|
|
|
using System;
|
2017-01-25 14:49:00 +01:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
2017-03-01 11:28:57 +01:00
|
|
|
|
using System.IO;
|
2017-01-25 14:49:00 +01:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2017-03-01 11:28:57 +01:00
|
|
|
|
using System.Threading;
|
2017-01-25 14:49:00 +01:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace OutlookRestarter
|
|
|
|
|
{
|
2017-05-18 11:06:18 +02:00
|
|
|
|
class OutlookRestarter
|
2017-01-25 14:49:00 +01:00
|
|
|
|
{
|
2017-05-22 10:02:52 +02:00
|
|
|
|
private const int FINISH_WAIT_TIME = 15000;
|
|
|
|
|
private const int DELETE_RETRIES = 30;
|
|
|
|
|
private const int DELETE_WAIT_TIME = 500;
|
2017-03-01 11:28:57 +01:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Entry point.
|
|
|
|
|
/// Arguments:
|
|
|
|
|
/// 0 - parent pid
|
|
|
|
|
/// 1 - parent path
|
|
|
|
|
/// 2 - arguments
|
|
|
|
|
/// n - ...
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="args"></param>
|
2017-01-25 14:49:00 +01:00
|
|
|
|
[STAThread]
|
|
|
|
|
static void Main(string[] args)
|
|
|
|
|
{
|
2017-05-22 10:02:52 +02:00
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Restarting: {0}: {1}", BuildVersions.VERSION, string.Join(", ", args));
|
2017-05-18 11:06:18 +02:00
|
|
|
|
|
2017-03-01 11:28:57 +01:00
|
|
|
|
try
|
|
|
|
|
{
|
2017-11-30 08:26:12 +01:00
|
|
|
|
int procId = int.Parse(args[0]);
|
|
|
|
|
string arch = args[1];
|
|
|
|
|
string procPath = args[2];
|
|
|
|
|
|
|
|
|
|
List<string> procArgs = args.Skip(3).ToList();
|
2017-09-06 08:32:09 +02:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting1");
|
|
|
|
|
// Attempt waiting for the process to finish
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting2");
|
|
|
|
|
Process proc = Process.GetProcessById(procId);
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting3");
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting for process to exit: {0}: {1}", procId, proc);
|
|
|
|
|
bool finished = proc.WaitForExit(FINISH_WAIT_TIME);
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waited for process to exit: {0}: {1}", procId, finished);
|
|
|
|
|
}
|
|
|
|
|
finally
|
2017-05-17 16:35:05 +02:00
|
|
|
|
{
|
2017-09-06 08:32:09 +02:00
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsing arguments");
|
|
|
|
|
List<string> useArgs = new List<string>();
|
|
|
|
|
for (int i = 0; i < procArgs.Count; ++i)
|
2017-05-17 16:35:05 +02:00
|
|
|
|
{
|
2017-09-06 08:32:09 +02:00
|
|
|
|
if (procArgs[i] == "/cleankoe")
|
|
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
string path = procArgs[i];
|
|
|
|
|
HandleCleanKoe(path);
|
|
|
|
|
}
|
2017-11-30 08:26:12 +01:00
|
|
|
|
else if (procArgs[i] == "/sharekoe")
|
|
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
HandleShareKoe(arch, procArgs[i]);
|
|
|
|
|
}
|
2017-09-14 14:21:32 +02:00
|
|
|
|
else if (procArgs[i].StartsWith("/"))
|
2017-05-17 16:35:05 +02:00
|
|
|
|
{
|
2017-09-06 08:32:09 +02:00
|
|
|
|
useArgs.Add(procArgs[i]);
|
|
|
|
|
}
|
2017-09-14 14:21:32 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
useArgs.Add("\"" + procArgs[i] + "\"");
|
|
|
|
|
}
|
2017-09-06 08:32:09 +02:00
|
|
|
|
}
|
|
|
|
|
string argsString = string.Join(" ", useArgs);
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsed arguments: {0}", argsString);
|
2017-11-30 08:26:12 +01:00
|
|
|
|
|
2017-09-06 08:32:09 +02:00
|
|
|
|
// Start the process
|
|
|
|
|
Process process = new Process();
|
|
|
|
|
process.StartInfo = new ProcessStartInfo(procPath, argsString);
|
2018-11-13 13:51:18 +01:00
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Starting process: {0} - {1}", procPath, argsString);
|
2017-09-06 08:32:09 +02:00
|
|
|
|
process.Start();
|
2018-11-13 13:51:18 +01:00
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Started process: {0} - {1}", procPath, argsString);
|
2017-09-06 08:32:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Fatal(typeof(OutlookRestarter), "Exception: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-22 10:02:52 +02:00
|
|
|
|
|
2017-11-30 08:26:12 +01:00
|
|
|
|
private static void HandleShareKoe(string arch, string rawArgs)
|
|
|
|
|
{
|
|
|
|
|
string baseDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
|
|
|
|
|
string path = Path.Combine(baseDir, "EASAccount-" + arch + ".exe");
|
|
|
|
|
string[] args = rawArgs.Split(':');
|
|
|
|
|
for (int i = 0; i < args.Length; ++i)
|
|
|
|
|
args[i] = "\"" + args[i] + "\"";
|
|
|
|
|
string argsString = string.Join(" ", args);
|
|
|
|
|
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to open account: {0}: {1}", path, argsString);
|
|
|
|
|
|
|
|
|
|
Process process = new Process();
|
|
|
|
|
process.StartInfo = new ProcessStartInfo(path, argsString);
|
|
|
|
|
process.StartInfo.CreateNoWindow = true;
|
|
|
|
|
process.StartInfo.UseShellExecute = false;
|
|
|
|
|
process.StartInfo.RedirectStandardOutput = true;
|
|
|
|
|
process.StartInfo.RedirectStandardError = true;
|
|
|
|
|
process.ErrorDataReceived += (s, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(e.Data.Trim()))
|
|
|
|
|
Logger.Instance.Warning(typeof(OutlookRestarter), "EASAccount: {0}", e.Data.Trim());
|
|
|
|
|
};
|
|
|
|
|
process.OutputDataReceived += (s, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(e.Data.Trim()))
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "EASAccount: {0}", e.Data.Trim());
|
|
|
|
|
};
|
|
|
|
|
process.Start();
|
|
|
|
|
process.BeginOutputReadLine();
|
|
|
|
|
process.BeginErrorReadLine();
|
|
|
|
|
process.WaitForExit(FINISH_WAIT_TIME);
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Opened accounts: {0}", argsString);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-06 08:32:09 +02:00
|
|
|
|
private static void HandleCleanKoe(string path)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to remove store: {0}", path);
|
|
|
|
|
if (Path.GetExtension(path) == ".ost")
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Info(typeof(OutlookRestarter), "Removing store: {0}", path);
|
2017-05-22 10:02:52 +02:00
|
|
|
|
|
2017-09-06 08:32:09 +02:00
|
|
|
|
for (int attempt = 0; attempt < DELETE_RETRIES; ++attempt)
|
|
|
|
|
{
|
|
|
|
|
// Delete it
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
File.Delete(path);
|
|
|
|
|
|
|
|
|
|
// Success, done
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
catch (IOException e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(typeof(OutlookRestarter), "IOException removing store: {0}: on attempt {1}: {2}", path, attempt, e);
|
|
|
|
|
// IO Exception. Wait a while and retry
|
|
|
|
|
Thread.Sleep(DELETE_WAIT_TIME);
|
2017-05-17 16:35:05 +02:00
|
|
|
|
}
|
2017-09-06 08:32:09 +02:00
|
|
|
|
catch (Exception e)
|
2017-05-17 16:35:05 +02:00
|
|
|
|
{
|
2017-09-06 08:32:09 +02:00
|
|
|
|
Logger.Instance.Error(typeof(OutlookRestarter), "Exception removing store: {0}: {1}", path, e);
|
|
|
|
|
// This kind of exception will not be resolved by retrying
|
|
|
|
|
break;
|
2017-05-17 16:35:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-01 11:28:57 +01:00
|
|
|
|
}
|
2017-01-25 14:49:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|