mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
[KOE-123] Added basic code to register an account on startup. Not working fully yet, just creates a store.
This commit is contained in:
parent
ba21bf0474
commit
4ea8432f0f
@ -355,6 +355,7 @@
|
||||
<Compile Include="Stubs\IPicture.cs" />
|
||||
<Compile Include="Stubs\IRecipient.cs" />
|
||||
<Compile Include="Stubs\IRecipients.cs" />
|
||||
<Compile Include="Stubs\IRestarter.cs" />
|
||||
<Compile Include="Stubs\ISignature.cs" />
|
||||
<Compile Include="Stubs\ISignatures.cs" />
|
||||
<Compile Include="Stubs\IStores.cs" />
|
||||
@ -375,6 +376,7 @@
|
||||
<Compile Include="Stubs\OutlookWrappers\RecipientsWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\InspectorsWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\Restarter.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\SignaturesWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\SignatureWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\StoresWrapper.cs" />
|
||||
|
@ -162,7 +162,9 @@ namespace Acacia.Features.SecondaryContacts
|
||||
MessageBoxIcon.Information
|
||||
) == DialogResult.Yes)
|
||||
{
|
||||
ThisAddIn.Instance.Restart(true);
|
||||
IRestarter restarter = ThisAddIn.Instance.Restarter();
|
||||
restarter.CloseWindows = true;
|
||||
restarter.Restart();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,7 @@
|
||||
this.kTreeFolders.NodePadding = new System.Windows.Forms.Padding(2, 4, 2, 4);
|
||||
this.kTreeFolders.CheckStateChanged += new Acacia.Controls.KTree.CheckStateChangedHandler(this.kTreeFolders_CheckStateChanged);
|
||||
this.kTreeFolders.SelectionChanged += new Acacia.Controls.KTree.SelectionChangedDelegate(this.kTreeFolders_SelectionChanged);
|
||||
this.kTreeFolders.DoubleClick += new System.EventHandler(this.kTreeFolders_DoubleClick);
|
||||
//
|
||||
// _layoutOptions
|
||||
//
|
||||
|
@ -576,5 +576,23 @@ namespace Acacia.Features.SharedFolders
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void kTreeFolders_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: This is some testing code for [KOE-123]
|
||||
/*
|
||||
if (ModifierKeys.HasFlag(Keys.Shift) && kTreeFolders.SelectedNodes.Count == 1)
|
||||
{
|
||||
KTreeNode selected = kTreeFolders.SelectedNodes.First();
|
||||
if (selected is StoreTreeNode)
|
||||
{
|
||||
// Open store for user
|
||||
Acacia.Stubs.IRestarter restarter = ThisAddIn.Instance.Restarter();
|
||||
restarter.CloseWindows = true;
|
||||
restarter.OpenShare(this._account, ((StoreTreeNode)selected).User);
|
||||
restarter.Restart();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +553,9 @@ namespace Acacia.Features.SyncState
|
||||
MessageBoxIcon.Error
|
||||
) == DialogResult.Yes)
|
||||
{
|
||||
ThisAddIn.Instance.RestartResync(account);
|
||||
IRestarter restarter = ThisAddIn.Instance.Restarter();
|
||||
restarter.ResyncAccounts(account);
|
||||
restarter.Restart();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -693,7 +695,9 @@ namespace Acacia.Features.SyncState
|
||||
|
||||
return true;
|
||||
case ResyncOption.Full:
|
||||
ThisAddIn.Instance.RestartResync(_accounts);
|
||||
IRestarter restarter = ThisAddIn.Instance.Restarter();
|
||||
restarter.ResyncAccounts(_accounts);
|
||||
restarter.Restart();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
@ -42,6 +42,7 @@ namespace Acacia.Stubs
|
||||
string DeviceId { get; }
|
||||
|
||||
SecureString Password { get; }
|
||||
byte[] EncryptedPassword { get; }
|
||||
|
||||
bool HasPassword { get; }
|
||||
|
||||
|
@ -66,13 +66,7 @@ namespace Acacia.Stubs
|
||||
/// <summary>
|
||||
/// Restarts the application
|
||||
/// </summary>
|
||||
void Restart(bool closeWindows);
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the application and removes the specified account files.
|
||||
/// </summary>
|
||||
/// <param name="accounts"></param>
|
||||
void RestartResync(params ZPushAccount[] accounts);
|
||||
IRestarter Restarter();
|
||||
|
||||
void Quit(bool closeWindows);
|
||||
|
||||
|
35
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IRestarter.cs
Normal file
35
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IRestarter.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Acacia.ZPush;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Acacia.Stubs
|
||||
{
|
||||
public interface IRestarter
|
||||
{
|
||||
/// <summary>
|
||||
/// Should any open windows be closed? Default is false.
|
||||
/// </summary>
|
||||
bool CloseWindows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds any accounts that need to be resynced.
|
||||
/// </summary>
|
||||
/// <param name="accounts"></param>
|
||||
void ResyncAccounts(params ZPushAccount[] accounts);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a share.
|
||||
/// </summary>
|
||||
/// <param name="account"></param>
|
||||
/// <param name="store"></param>
|
||||
void OpenShare(ZPushAccount account, GABUser store);
|
||||
|
||||
/// <summary>
|
||||
/// Performs the actual restart.
|
||||
/// </summary>
|
||||
void Restart();
|
||||
}
|
||||
}
|
@ -160,8 +160,15 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] encrypted = (byte[])Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null);
|
||||
return PasswordEncryption.Decrypt(encrypted);
|
||||
return PasswordEncryption.Decrypt(EncryptedPassword);
|
||||
}
|
||||
}
|
||||
[Browsable(false)]
|
||||
public byte[] EncryptedPassword
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte[])Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,56 +156,9 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
_stores.Start();
|
||||
}
|
||||
|
||||
public void Restart(bool closeWindows)
|
||||
public IRestarter Restarter()
|
||||
{
|
||||
DoRestart(closeWindows, null);
|
||||
}
|
||||
|
||||
private void DoRestart(bool closeWindows, string additionalCommandLine)
|
||||
{
|
||||
// Can not use the assembly location, as that is in the GAC
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
UriBuilder uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
// Create the path to the restarter
|
||||
path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), "OutlookRestarter.exe");
|
||||
|
||||
// Use the current command line, with a profile command if not specified
|
||||
string commandLine = Environment.CommandLine;
|
||||
// This selects both /profile and /profiles. In that case we don't specify the profile, otherwise
|
||||
// we specify the current profile
|
||||
// It seems to be impossible to escape a profile name with a quote, so in that case ignore it
|
||||
if (!commandLine.ToLower().Contains("/profile") && !ProfileName.Contains("\""))
|
||||
{
|
||||
commandLine += " /profile " + Util.QuoteCommandLine(ProfileName);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(additionalCommandLine))
|
||||
{
|
||||
commandLine = commandLine + " " + additionalCommandLine;
|
||||
}
|
||||
|
||||
// Run that
|
||||
Process process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo(path, Process.GetCurrentProcess().Id + " " + commandLine);
|
||||
process.Start();
|
||||
|
||||
// And close us and any other windows
|
||||
Quit(closeWindows);
|
||||
}
|
||||
|
||||
public void RestartResync(ZPushAccount[] accounts)
|
||||
{
|
||||
string commandLine = "";
|
||||
foreach(ZPushAccount account in accounts)
|
||||
{
|
||||
string path = account.Account.BackingFilePath;
|
||||
if (!string.IsNullOrEmpty(path) && System.IO.Path.GetExtension(path) == ".ost")
|
||||
{
|
||||
commandLine += "/cleankoe " + Util.QuoteCommandLine(path);
|
||||
}
|
||||
}
|
||||
DoRestart(true, commandLine);
|
||||
return new Restarter(this);
|
||||
}
|
||||
|
||||
public void Quit(bool closeWindows)
|
||||
|
@ -0,0 +1,104 @@
|
||||
using Acacia.Utils;
|
||||
using Acacia.ZPush;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
class Restarter : IRestarter
|
||||
{
|
||||
private readonly AddInWrapper _addIn;
|
||||
private readonly List<ZPushAccount> _resyncAccounts = new List<ZPushAccount>();
|
||||
private readonly List<KeyValuePair<ZPushAccount, GABUser>> _shares = new List<KeyValuePair<ZPushAccount, GABUser>>();
|
||||
|
||||
public Restarter(AddInWrapper addIn)
|
||||
{
|
||||
this._addIn = addIn;
|
||||
}
|
||||
|
||||
public bool CloseWindows
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private string RestarterPath
|
||||
{
|
||||
get
|
||||
{
|
||||
// Can not use the assembly location, as that is in the GAC
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
UriBuilder uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
// Create the path to the restarter
|
||||
return System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), "OutlookRestarter.exe");
|
||||
}
|
||||
}
|
||||
|
||||
public void ResyncAccounts(params ZPushAccount[] accounts)
|
||||
{
|
||||
_resyncAccounts.AddRange(accounts);
|
||||
}
|
||||
|
||||
public void OpenShare(ZPushAccount account, GABUser store)
|
||||
{
|
||||
_shares.Add(new KeyValuePair<ZPushAccount, GABUser>(account, store));
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
// Use the current command line, with a profile command if not specified
|
||||
string commandLine = Environment.CommandLine;
|
||||
// This selects both /profile and /profiles. In that case we don't specify the profile, otherwise
|
||||
// we specify the current profile
|
||||
// It seems to be impossible to escape a profile name with a quote, so in that case ignore it
|
||||
if (!commandLine.ToLower().Contains("/profile") && !_addIn.ProfileName.Contains("\""))
|
||||
{
|
||||
commandLine += " /profile " + Util.QuoteCommandLine(_addIn.ProfileName);
|
||||
}
|
||||
|
||||
// Custom command line
|
||||
foreach (ZPushAccount account in _resyncAccounts)
|
||||
{
|
||||
string path = account.Account.BackingFilePath;
|
||||
if (!string.IsNullOrEmpty(path) && System.IO.Path.GetExtension(path) == ".ost")
|
||||
{
|
||||
commandLine += " /cleankoe" + Util.QuoteCommandLine(path);
|
||||
}
|
||||
}
|
||||
foreach(KeyValuePair<ZPushAccount, GABUser> share in _shares)
|
||||
{
|
||||
using (RegistryKey key = OutlookRegistryUtils.OpenProfileOutlookKey(_addIn.ProfileName, RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
{
|
||||
int accountId = (int)key.GetValue(OutlookConstants.REG_VAL_NEXT_ACCOUNT_ID);
|
||||
using (RegistryKey accountKey = key.CreateSubKey(string.Format("{0:X8}", accountId)))
|
||||
{
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_ACCOUNTNAME, share.Value.UserName + " through " + share.Key.DisplayName);
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_DISPLAYNAME, "Share for " + share.Value.DisplayName);
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_EMAIL, "test" + share.Key.Account.SmtpAddress);
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_SERVER, share.Key.Account.ServerURL);
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_USERNAME, share.Key.Account.UserName + ".share." + share.Value.UserName);
|
||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_PASSWORD, share.Key.Account.EncryptedPassword);
|
||||
//accountKey.SetValue(OutlookConstants.REG_VAL_EAS_DEVICEID, share.Key.Account.DeviceId);
|
||||
accountKey.SetValue("clsid", "{ED475415-B0D6-11D2-8C3B-00104B2A6676}");
|
||||
}
|
||||
key.SetValue(OutlookConstants.REG_VAL_NEXT_ACCOUNT_ID, accountId + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Run that
|
||||
Process process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo(RestarterPath, Process.GetCurrentProcess().Id + " " + commandLine);
|
||||
process.Start();
|
||||
|
||||
// And close us and any other windows
|
||||
_addIn.Quit(CloseWindows);
|
||||
}
|
||||
}
|
||||
}
|
@ -292,8 +292,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
NSOutlook.NameSpace session = _item.Session;
|
||||
try
|
||||
{
|
||||
string path = string.Format(OutlookConstants.REG_SUBKEY_ACCOUNTS, session.CurrentProfileName);
|
||||
return OutlookRegistryUtils.OpenOutlookKey(path);
|
||||
return OutlookRegistryUtils.OpenProfileOutlookKey(session.CurrentProfileName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -25,6 +25,11 @@ namespace Acacia.Utils
|
||||
{
|
||||
public static class OutlookRegistryUtils
|
||||
{
|
||||
public static RegistryKey OpenProfileOutlookKey(string profile, RegistryKeyPermissionCheck permissions = RegistryKeyPermissionCheck.Default)
|
||||
{
|
||||
string path = string.Format(OutlookConstants.REG_SUBKEY_ACCOUNTS, profile);
|
||||
return OpenOutlookKey(path, permissions);
|
||||
}
|
||||
|
||||
public static RegistryKey OpenOutlookKey(string suffix = null, RegistryKeyPermissionCheck permissions = RegistryKeyPermissionCheck.Default)
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
using Acacia;
|
||||
using Acacia.Utils;
|
||||
using Microsoft.Win32;
|
||||
/// Copyright 2017 Kopano b.v.
|
||||
///
|
||||
/// This program is free software: you can redistribute it and/or modify
|
||||
@ -46,70 +48,85 @@ namespace OutlookRestarter
|
||||
{
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Restarting: {0}: {1}", BuildVersions.VERSION, string.Join(", ", args));
|
||||
|
||||
string procPath = args[1];
|
||||
List<string> procArgs = args.Skip(2).ToList();
|
||||
try
|
||||
{
|
||||
// Attempt waiting for the process to finish
|
||||
int procId = int.Parse(args[0]);
|
||||
Process proc = Process.GetProcessById(procId);
|
||||
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
|
||||
{
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsing arguments");
|
||||
List<string> useArgs = new List<string>();
|
||||
for (int i = 0; i < procArgs.Count; ++i)
|
||||
string procPath = args[1];
|
||||
List<string> procArgs = args.Skip(2).ToList();
|
||||
try
|
||||
{
|
||||
if (procArgs[i] == "/cleankoe")
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting1");
|
||||
// Attempt waiting for the process to finish
|
||||
int procId = int.Parse(args[0]);
|
||||
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
|
||||
{
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsing arguments");
|
||||
List<string> useArgs = new List<string>();
|
||||
for (int i = 0; i < procArgs.Count; ++i)
|
||||
{
|
||||
++i;
|
||||
string path = procArgs[i];
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to remove store: {0}", path);
|
||||
if (System.IO.Path.GetExtension(path) == ".ost")
|
||||
if (procArgs[i] == "/cleankoe")
|
||||
{
|
||||
Logger.Instance.Info(typeof(OutlookRestarter), "Removing store: {0}", path);
|
||||
|
||||
for (int attempt = 0; attempt < DELETE_RETRIES; ++attempt)
|
||||
{
|
||||
// Delete it
|
||||
try
|
||||
{
|
||||
System.IO.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);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Error(typeof(OutlookRestarter), "Exception removing store: {0}: {1}", path, e);
|
||||
// This kind of exception will not be resolved by retrying
|
||||
break;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
string path = procArgs[i];
|
||||
HandleCleanKoe(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
useArgs.Add(procArgs[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
string argsString = string.Join(" ", useArgs);
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsed arguments: {0}", argsString);
|
||||
// Start the process
|
||||
Process process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo(procPath, argsString);
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Starting process: {0}", process);
|
||||
process.Start();
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Started process: {0}", process);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logger.Instance.Fatal(typeof(OutlookRestarter), "Exception: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (int attempt = 0; attempt < DELETE_RETRIES; ++attempt)
|
||||
{
|
||||
// Delete it
|
||||
try
|
||||
{
|
||||
useArgs.Add(procArgs[i]);
|
||||
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);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Error(typeof(OutlookRestarter), "Exception removing store: {0}: {1}", path, e);
|
||||
// This kind of exception will not be resolved by retrying
|
||||
break;
|
||||
}
|
||||
}
|
||||
string argsString = string.Join(" ", useArgs);
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsed arguments: {0}", argsString);
|
||||
// Start the process
|
||||
Process process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo(procPath, argsString);
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Starting process: {0}", process);
|
||||
process.Start();
|
||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Started process: {0}", process);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user