mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
Cleaned up account checking
This commit is contained in:
parent
d4b03c2eb9
commit
cb32513ed3
@ -280,6 +280,7 @@
|
||||
<Compile Include="Native\IOleWindow.cs" />
|
||||
<Compile Include="OutlookConstants.cs" />
|
||||
<Compile Include="Stubs\Enums.cs" />
|
||||
<Compile Include="Stubs\IAccount.cs" />
|
||||
<Compile Include="Stubs\IAddIn.cs" />
|
||||
<Compile Include="Stubs\IAddressEntry.cs" />
|
||||
<Compile Include="Stubs\ICommandBars.cs" />
|
||||
@ -288,7 +289,9 @@
|
||||
<Compile Include="Stubs\IItemEvents.cs" />
|
||||
<Compile Include="Stubs\IOutlookWindow.cs" />
|
||||
<Compile Include="Stubs\IRecipient.cs" />
|
||||
<Compile Include="Stubs\IStores.cs" />
|
||||
<Compile Include="Stubs\ISyncObject.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\AccountWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
|
||||
@ -296,6 +299,7 @@
|
||||
<Compile Include="Stubs\OutlookWrappers\ItemEventsWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\OutlookItemWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\StoresWrapper.cs" />
|
||||
<Compile Include="Stubs\OutlookWrappers\SyncObjectWrapper.cs" />
|
||||
<Compile Include="Stubs\Wrappers.cs" />
|
||||
<Compile Include="UI\Outlook\OutlookImageList.cs" />
|
||||
|
@ -103,7 +103,7 @@ namespace Acacia.Features.FreeBusy
|
||||
|
||||
set
|
||||
{
|
||||
RegistryUtil.SetConfigValue(Name, REG_DEFAULTACCOUNT, value == null ? "" : value.SmtpAddress, RegistryValueKind.String);
|
||||
RegistryUtil.SetConfigValue(Name, REG_DEFAULTACCOUNT, value == null ? "" : value.Account.SmtpAddress, RegistryValueKind.String);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using Acacia.UI;
|
||||
using static Acacia.DebugOptions;
|
||||
using Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.Features.GAB
|
||||
{
|
||||
@ -474,7 +473,7 @@ namespace Acacia.Features.GAB
|
||||
private void AccountDiscovered(ZPushAccount zpush)
|
||||
{
|
||||
Logger.Instance.Info(this, "Account discovered: {0}", zpush.DisplayName);
|
||||
_domains.Add(zpush.DomainName);
|
||||
_domains.Add(zpush.Account.DomainName);
|
||||
|
||||
zpush.ConfirmedChanged += (z) =>
|
||||
{
|
||||
@ -606,7 +605,7 @@ namespace Acacia.Features.GAB
|
||||
private void RegisterGABAccount(ZPushAccount account, IFolder folder)
|
||||
{
|
||||
// Determine the domain name
|
||||
string domain = account.DomainName;
|
||||
string domain = account.Account.DomainName;
|
||||
|
||||
// Could already be registered if there are multiple accounts on the same domain
|
||||
GABHandler gab;
|
||||
@ -637,7 +636,7 @@ namespace Acacia.Features.GAB
|
||||
|
||||
private void ZPushChannelAvailable(IFolder folder)
|
||||
{
|
||||
using (IStore store = folder.Store)
|
||||
using (IStore store = folder.GetStore())
|
||||
{
|
||||
Logger.Instance.Debug(this, "Z-Push channel available: {0} on {1}", folder, store.DisplayName);
|
||||
|
||||
|
@ -121,7 +121,7 @@ namespace Acacia.Features.GAB
|
||||
{
|
||||
get
|
||||
{
|
||||
using(IStore store = Folder.Store)
|
||||
using(IStore store = Folder.GetStore())
|
||||
return store.DisplayName;
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ namespace Acacia.Features.OutOfOffice
|
||||
if (oof.State != ActiveSync.OOFState.Disabled)
|
||||
{
|
||||
if (MessageBox.Show(
|
||||
string.Format(Properties.Resources.OOFStartup_Message, account.SmtpAddress),
|
||||
string.Format(Properties.Resources.OOFStartup_Message, account.Account.SmtpAddress),
|
||||
Properties.Resources.OOFStartup_Title,
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question
|
||||
|
@ -43,7 +43,7 @@ namespace Acacia.Features.OutOfOffice
|
||||
InitializeComponent();
|
||||
|
||||
// Add the email address to the title
|
||||
Text = string.Format(Text, account.SmtpAddress);
|
||||
Text = string.Format(Text, account.Account.SmtpAddress);
|
||||
|
||||
// Set the time formats
|
||||
timeFrom.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern;
|
||||
|
@ -71,7 +71,7 @@ namespace Acacia.Features.SendAs
|
||||
private void MailEvents_Respond(IMailItem mail, IMailItem response)
|
||||
{
|
||||
Logger.Instance.Trace(this, "Responding to mail, checking");
|
||||
using (IStore store = mail.Store)
|
||||
using (IStore store = mail.GetStore())
|
||||
{
|
||||
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
|
||||
Logger.Instance.Trace(this, "Checking ZPush: {0}", zpush);
|
||||
@ -114,13 +114,13 @@ namespace Acacia.Features.SendAs
|
||||
|
||||
private void MailEvents_ItemSend(IMailItem item, ref bool cancel)
|
||||
{
|
||||
using (IStore store = item.Store)
|
||||
using (IStore store = item.GetStore())
|
||||
{
|
||||
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
|
||||
if (zpush != null)
|
||||
{
|
||||
string address = item.SenderEmailAddress;
|
||||
if (address != null && address != zpush.SmtpAddress)
|
||||
if (address != null && address != zpush.Account.SmtpAddress)
|
||||
{
|
||||
Logger.Instance.Trace(this, "SendAs: {0}: {1}", address, item.SenderName);
|
||||
item.SetProperty(Constants.ZPUSH_SEND_AS, address);
|
||||
|
@ -71,7 +71,7 @@ namespace Acacia.Features.SharedFolders
|
||||
).Images;
|
||||
|
||||
// Add the email address to the title
|
||||
Text = string.Format(Text, account.SmtpAddress);
|
||||
Text = string.Format(Text, account.Account.SmtpAddress);
|
||||
|
||||
// Set up options
|
||||
ShowOptions(new KTreeNode[0]);
|
||||
|
@ -100,15 +100,15 @@ namespace Acacia.Features.WebApp
|
||||
// Perform a cached auto discover
|
||||
try
|
||||
{
|
||||
Logger.Instance.Debug(this, "Starting kdiscover: {0}", account.DomainName);
|
||||
Logger.Instance.Debug(this, "Starting kdiscover: {0}", account.Account.DomainName);
|
||||
string url = PerformAutoDiscover(account);
|
||||
Logger.Instance.Debug(this, "Finished kdiscover: {0}: {1}", account.DomainName, url);
|
||||
Logger.Instance.Debug(this, "Finished kdiscover: {0}: {1}", account.Account.DomainName, url);
|
||||
account.SetFeatureData(this, TXT_KDISCOVER, new URLCached(url));
|
||||
return url;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Warning(this, "Exception during kdiscover: {0}: {1}", account.DomainName, e);
|
||||
Logger.Instance.Warning(this, "Exception during kdiscover: {0}: {1}", account.Account.DomainName, e);
|
||||
account.SetFeatureData(this, TXT_KDISCOVER, null);
|
||||
return null;
|
||||
}
|
||||
@ -117,7 +117,7 @@ namespace Acacia.Features.WebApp
|
||||
private string PerformAutoDiscover(ZPushAccount account)
|
||||
{
|
||||
// Fetch the txt record
|
||||
IList<string> txt = DnsUtil.GetTxtRecord(account.DomainName);
|
||||
IList<string> txt = DnsUtil.GetTxtRecord(account.Account.DomainName);
|
||||
if (txt == null)
|
||||
return null;
|
||||
|
||||
|
@ -45,4 +45,11 @@ namespace Acacia.Stubs
|
||||
ManagedEmail = 29,
|
||||
SuggestedContacts = 30
|
||||
}
|
||||
|
||||
public enum AccountType
|
||||
{
|
||||
// TODO
|
||||
EAS,
|
||||
Other
|
||||
}
|
||||
}
|
||||
|
35
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs
Normal file
35
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Acacia.Stubs
|
||||
{
|
||||
public interface IAccount : IDisposable
|
||||
{
|
||||
AccountType AccountType { get; }
|
||||
|
||||
IStore Store { get; }
|
||||
|
||||
string DisplayName { get; }
|
||||
|
||||
string SmtpAddress { get; }
|
||||
|
||||
string UserName { get; }
|
||||
|
||||
string ServerURL { get; }
|
||||
|
||||
string DeviceId { get; }
|
||||
|
||||
SecureString Password { get; }
|
||||
|
||||
bool HasPassword { get; }
|
||||
|
||||
string StoreID { get; }
|
||||
|
||||
string DomainName { get; }
|
||||
|
||||
}
|
||||
}
|
@ -44,9 +44,9 @@ namespace Acacia.Stubs
|
||||
// TODO: clean this up
|
||||
|
||||
/// <summary>
|
||||
/// Sends and receives all accounts.
|
||||
/// Sends and receives all accounts, or a specific account.
|
||||
/// </summary>
|
||||
void SendReceive();
|
||||
void SendReceive(IAccount account = null);
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the application
|
||||
@ -63,12 +63,13 @@ namespace Acacia.Stubs
|
||||
|
||||
IRecipient ResolveRecipient(string name);
|
||||
|
||||
IStore AddFileStore(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the stores. The caller is responsible for disposing.
|
||||
/// Returns the store manager. This is a shared object and must NOT be disposed.
|
||||
/// </summary>
|
||||
IEnumerable<IStore> Stores { get; }
|
||||
IStores Stores
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -42,14 +42,13 @@ namespace Acacia.Stubs
|
||||
|
||||
/// <summary>
|
||||
/// Returns the store. The owner is responsible for disposing.
|
||||
/// TODO: make method to make disposing clear
|
||||
/// </summary>
|
||||
IStore Store { get; }
|
||||
IStore GetStore();
|
||||
|
||||
/// <summary>
|
||||
/// Quick accessor to Store.Id, to prevent allocating a wrapper for it.
|
||||
/// </summary>
|
||||
string StoreId { get; }
|
||||
string StoreID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Quick accessor to Store.DisplayName, to prevent allocating a wrapper for it.
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
||||
using NSOutlookDelegates = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.Stubs
|
||||
{
|
||||
@ -12,32 +12,32 @@ namespace Acacia.Stubs
|
||||
#region Event handlers
|
||||
|
||||
// TODO: custom delegates
|
||||
event NSOutlook.ItemEvents_10_AfterWriteEventHandler AfterWrite;
|
||||
event NSOutlook.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
|
||||
event NSOutlook.ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
|
||||
event NSOutlook.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
|
||||
event NSOutlook.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
|
||||
event NSOutlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
|
||||
event NSOutlook.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
|
||||
event NSOutlook.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
|
||||
event NSOutlook.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
|
||||
event NSOutlook.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
|
||||
event NSOutlook.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
|
||||
event NSOutlook.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
|
||||
event NSOutlook.ItemEvents_10_BeforeReadEventHandler BeforeRead;
|
||||
event NSOutlook.ItemEvents_10_CloseEventHandler Close;
|
||||
event NSOutlook.ItemEvents_10_CustomActionEventHandler CustomAction;
|
||||
event NSOutlook.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
|
||||
event NSOutlook.ItemEvents_10_ForwardEventHandler Forward;
|
||||
event NSOutlook.ItemEvents_10_OpenEventHandler Open;
|
||||
event NSOutlook.ItemEvents_10_PropertyChangeEventHandler PropertyChange;
|
||||
event NSOutlook.ItemEvents_10_ReadEventHandler Read;
|
||||
event NSOutlook.ItemEvents_10_ReadCompleteEventHandler ReadComplete;
|
||||
event NSOutlook.ItemEvents_10_ReplyEventHandler Reply;
|
||||
event NSOutlook.ItemEvents_10_ReplyAllEventHandler ReplyAll;
|
||||
event NSOutlook.ItemEvents_10_SendEventHandler Send;
|
||||
event NSOutlook.ItemEvents_10_UnloadEventHandler Unload;
|
||||
event NSOutlook.ItemEvents_10_WriteEventHandler Write;
|
||||
event NSOutlookDelegates.ItemEvents_10_AfterWriteEventHandler AfterWrite;
|
||||
event NSOutlookDelegates.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
|
||||
event NSOutlookDelegates.ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
|
||||
event NSOutlookDelegates.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
|
||||
event NSOutlookDelegates.ItemEvents_10_BeforeReadEventHandler BeforeRead;
|
||||
event NSOutlookDelegates.ItemEvents_10_CloseEventHandler Close;
|
||||
event NSOutlookDelegates.ItemEvents_10_CustomActionEventHandler CustomAction;
|
||||
event NSOutlookDelegates.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
|
||||
event NSOutlookDelegates.ItemEvents_10_ForwardEventHandler Forward;
|
||||
event NSOutlookDelegates.ItemEvents_10_OpenEventHandler Open;
|
||||
event NSOutlookDelegates.ItemEvents_10_PropertyChangeEventHandler PropertyChange;
|
||||
event NSOutlookDelegates.ItemEvents_10_ReadEventHandler Read;
|
||||
event NSOutlookDelegates.ItemEvents_10_ReadCompleteEventHandler ReadComplete;
|
||||
event NSOutlookDelegates.ItemEvents_10_ReplyEventHandler Reply;
|
||||
event NSOutlookDelegates.ItemEvents_10_ReplyAllEventHandler ReplyAll;
|
||||
event NSOutlookDelegates.ItemEvents_10_SendEventHandler Send;
|
||||
event NSOutlookDelegates.ItemEvents_10_UnloadEventHandler Unload;
|
||||
event NSOutlookDelegates.ItemEvents_10_WriteEventHandler Write;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
32
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStores.cs
Normal file
32
src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStores.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Acacia.Stubs
|
||||
{
|
||||
public delegate void IStores_AccountDiscovered(IAccount account);
|
||||
public delegate void IStores_AccountRemoved(IAccount account);
|
||||
|
||||
/// <summary>
|
||||
/// Manages the stores and associated acounts.
|
||||
/// </summary>
|
||||
public interface IStores: IComWrapper, IEnumerable<IStore>
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the accounts. The accounts are shared objects and must not be disposed.
|
||||
/// </summary>
|
||||
IEnumerable<IAccount> Accounts { get; }
|
||||
|
||||
event IStores_AccountDiscovered AccountDiscovered;
|
||||
event IStores_AccountRemoved AccountRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a file store to the current collection. If the store is already in the collection, an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>The store. The caller is responsible for disposing.</returns>
|
||||
IStore AddFileStore(string path);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
||||
using NSOutlookDelegates = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.Stubs
|
||||
{
|
||||
@ -25,10 +25,10 @@ namespace Acacia.Stubs
|
||||
|
||||
#region Events
|
||||
// TODO: custom delegates
|
||||
event NSOutlook.SyncObjectEvents_OnErrorEventHandler OnError;
|
||||
event NSOutlook.SyncObjectEvents_ProgressEventHandler Progress;
|
||||
event NSOutlook.SyncObjectEvents_SyncEndEventHandler SyncEnd;
|
||||
event NSOutlook.SyncObjectEvents_SyncStartEventHandler SyncStart;
|
||||
event NSOutlookDelegates.SyncObjectEvents_OnErrorEventHandler OnError;
|
||||
event NSOutlookDelegates.SyncObjectEvents_ProgressEventHandler Progress;
|
||||
event NSOutlookDelegates.SyncObjectEvents_SyncEndEventHandler SyncEnd;
|
||||
event NSOutlookDelegates.SyncObjectEvents_SyncStartEventHandler SyncStart;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,153 @@
|
||||
using Acacia.Utils;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
class AccountWrapper : DisposableWrapper, IAccount, LogContext
|
||||
{
|
||||
private readonly string _regPath;
|
||||
private readonly IStore _store;
|
||||
|
||||
internal AccountWrapper(string regPath, IStore store)
|
||||
{
|
||||
this._regPath = regPath;
|
||||
this._store = store;
|
||||
|
||||
// Cache the SmtpAddress, it is used as the key
|
||||
SmtpAddress = RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EMAIL, null);
|
||||
}
|
||||
|
||||
protected override void DoRelease()
|
||||
{
|
||||
_store.Dispose();
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public string LogContextId
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ZPushAccount(" + SmtpAddress + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return SmtpAddress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers an Outlook send/receive operation.
|
||||
/// </summary>
|
||||
public void SendReceive()
|
||||
{
|
||||
// TODO: ThisAddIn.Instance.SendReceive();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public AccountType AccountType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DeviceId == null) ? AccountType.Other : AccountType.EAS;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
{
|
||||
return _store;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_DISPLAYNAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string SmtpAddress
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_USERNAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string ServerURL
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_SERVER, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string DeviceId
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_DEVICEID, null);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public SecureString Password
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] encrypted = (byte[])Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null);
|
||||
return PasswordEncryption.Decrypt(encrypted);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public bool HasPassword
|
||||
{
|
||||
get { return Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null) != null; }
|
||||
}
|
||||
|
||||
public string StoreID
|
||||
{
|
||||
get { return GetStoreId(_regPath); }
|
||||
}
|
||||
|
||||
public static string GetStoreId(string regPath)
|
||||
{
|
||||
return StringUtil.BytesToHex((byte[])Registry.GetValue(regPath, OutlookConstants.REG_VAL_EAS_STOREID, null));
|
||||
}
|
||||
|
||||
public string DomainName
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = SmtpAddress.IndexOf('@');
|
||||
if (index < 0)
|
||||
return SmtpAddress;
|
||||
else
|
||||
return SmtpAddress.Substring(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -17,17 +17,29 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
public class AddInWrapper : IAddIn
|
||||
{
|
||||
private readonly NSOutlook.Application _app;
|
||||
private readonly ThisAddIn _thisAddIn;
|
||||
private NSOutlook.Application _app;
|
||||
private readonly StoresWrapper _stores;
|
||||
|
||||
public AddInWrapper(ThisAddIn thisAddIn)
|
||||
{
|
||||
this._thisAddIn = thisAddIn;
|
||||
this._app = thisAddIn.Application;
|
||||
|
||||
NSOutlook.NameSpace session = _app.Session;
|
||||
try
|
||||
{
|
||||
this._stores = new StoresWrapper(session.Stores);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ComRelease.Release(session);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendReceive()
|
||||
public void SendReceive(IAccount account)
|
||||
{
|
||||
// TODO: send/receive specific account
|
||||
NSOutlook.NameSpace session = _app.Session;
|
||||
try
|
||||
{
|
||||
@ -39,6 +51,11 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_stores.Start();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
// Can not use the assembly location, as that is in the GAC
|
||||
@ -224,35 +241,9 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore AddFileStore(string path)
|
||||
public IStores Stores
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
NSOutlook.NameSpace session = com.Add(_app.Session);
|
||||
|
||||
// Add the store
|
||||
session.AddStore(path);
|
||||
|
||||
// And fetch it and wrap
|
||||
NSOutlook.Stores stores = com.Add(session.Stores);
|
||||
return Mapping.Wrap(stores[stores.Count]);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IStore> Stores
|
||||
{
|
||||
get
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
NSOutlook.NameSpace session = com.Add(_app.Session);
|
||||
NSOutlook.Stores stores = com.Add(session.Stores);
|
||||
foreach (NSOutlook.Store store in stores)
|
||||
{
|
||||
yield return Mapping.Wrap(store);
|
||||
}
|
||||
}
|
||||
}
|
||||
get { return _stores; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,9 +116,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -126,9 +124,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -241,9 +241,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -251,9 +249,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -257,9 +257,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -267,9 +265,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -100,13 +100,13 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
|
||||
public string EntryID { get { return _item.EntryID; } }
|
||||
|
||||
public IStore Store { get { return Mapping.Wrap(_item.Store); } }
|
||||
public IStore GetStore() { return Mapping.Wrap(_item.Store); }
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
using (IStore store = Store)
|
||||
using (IStore store = GetStore())
|
||||
{
|
||||
return store.StoreID;
|
||||
}
|
||||
@ -116,7 +116,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
using (IStore store = Store)
|
||||
using (IStore store = GetStore())
|
||||
{
|
||||
return store.DisplayName;
|
||||
}
|
||||
@ -241,7 +241,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStore store = Store)
|
||||
using (IStore store = GetStore())
|
||||
{
|
||||
return store.GetItemFromID(entryId);
|
||||
}
|
||||
|
@ -150,9 +150,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -160,9 +158,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -97,9 +97,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -107,9 +105,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -95,9 +95,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -105,9 +103,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -0,0 +1,270 @@
|
||||
using Acacia.Utils;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.Stubs.OutlookWrappers
|
||||
{
|
||||
class StoresWrapper : ComWrapper<NSOutlook.Stores>, IStores
|
||||
{
|
||||
/// <summary>
|
||||
/// Accounts indexed by store id. Null values are allowed, if a store has been
|
||||
/// determined to not be associated with an Account. This is required to determine when a store is new.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, AccountWrapper> _accountsByStoreId = new Dictionary<string, AccountWrapper>();
|
||||
|
||||
/// <summary>
|
||||
/// Accounts indexed by SMTPAddress. Null values are not allowed.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, AccountWrapper> _accountsBySmtp = new Dictionary<string, AccountWrapper>();
|
||||
|
||||
public StoresWrapper(NSOutlook.Stores item) : base(item)
|
||||
{
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public event IStores_AccountDiscovered AccountDiscovered;
|
||||
public event IStores_AccountRemoved AccountRemoved;
|
||||
|
||||
private void OnAccountDiscovered(AccountWrapper account)
|
||||
{
|
||||
AccountDiscovered?.Invoke(account);
|
||||
}
|
||||
|
||||
private void OnAccountRemoved(AccountWrapper account)
|
||||
{
|
||||
AccountRemoved?.Invoke(account);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// Check existing stores
|
||||
// TODO: do this in background?
|
||||
foreach(NSOutlook.Store store in _item)
|
||||
{
|
||||
StoreAdded(store);
|
||||
}
|
||||
|
||||
// Register for new stores
|
||||
// The store remove event is not sent, so don't bother registering for that
|
||||
_item.StoreAdd += StoreAdded;
|
||||
|
||||
|
||||
if (GlobalOptions.INSTANCE.AccountTimer)
|
||||
{
|
||||
// Set up timer to check for removed accounts
|
||||
Util.Timed(null, Config.ACCOUNT_CHECK_INTERVAL, CheckAccountsRemoved);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for Stores.StoreAdded event.
|
||||
/// </summary>
|
||||
private void StoreAdded(NSOutlook.Store s)
|
||||
{
|
||||
IStore store = null;
|
||||
try
|
||||
{
|
||||
// Accessing the store object causes random crashes, simply iterate to find new stores
|
||||
Logger.Instance.Trace(this, "StoreAdded: {0}", s.StoreID);
|
||||
foreach (NSOutlook.Store rawStore in _item)
|
||||
{
|
||||
if (!_accountsByStoreId.ContainsKey(rawStore.StoreID))
|
||||
{
|
||||
store = new StoreWrapper(rawStore);
|
||||
Logger.Instance.Trace(this, "New store: {0}", rawStore.DisplayName);
|
||||
AccountWrapper account = TryCreateFromRegistry(store);
|
||||
if (account == null)
|
||||
{
|
||||
// Add it to the cache so it is not evaluated again.
|
||||
_accountsByStoreId.Add(store.StoreID, null);
|
||||
Logger.Instance.Trace(this, "Not an account store: {0}", store.DisplayName);
|
||||
store.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Account has taken ownership of the store
|
||||
Logger.Instance.Trace(this, "New account store: {0}: {1}", store.DisplayName, account);
|
||||
OnAccountDiscovered(account);
|
||||
}
|
||||
}
|
||||
else ComRelease.Release(rawStore);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "StoreAdded Exception: {0}", e);
|
||||
if (store != null)
|
||||
store.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAccountsRemoved()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Collect all the store ids
|
||||
HashSet<string> stores = new HashSet<string>();
|
||||
foreach (NSOutlook.Store store in _item)
|
||||
{
|
||||
try
|
||||
{
|
||||
stores.Add(store.StoreID);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ComRelease.Release(store);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any relevant ones are removed
|
||||
List<KeyValuePair<string, AccountWrapper>> removed = new List<KeyValuePair<string, AccountWrapper>>();
|
||||
foreach (KeyValuePair<string, AccountWrapper> account in _accountsByStoreId)
|
||||
{
|
||||
if (!stores.Contains(account.Key))
|
||||
{
|
||||
Logger.Instance.Trace(this, "Store not found: {0} - {1}", account.Value, account.Key);
|
||||
removed.Add(account);
|
||||
}
|
||||
}
|
||||
|
||||
// Process any removed stores
|
||||
foreach (KeyValuePair<string, AccountWrapper> remove in removed)
|
||||
{
|
||||
Logger.Instance.Debug(this, "Account removed: {0} - {1}", remove.Value, remove.Key);
|
||||
_accountsBySmtp.Remove(remove.Value.SmtpAddress);
|
||||
_accountsByStoreId.Remove(remove.Key);
|
||||
OnAccountRemoved(remove.Value);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "Exception in CheckAccountsRemoved: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public interface
|
||||
|
||||
public IStore AddFileStore(string path)
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
NSOutlook.NameSpace session = com.Add(_item.Session);
|
||||
|
||||
// Add the store
|
||||
session.AddStore(path);
|
||||
|
||||
// And fetch it and wrap
|
||||
return Mapping.Wrap(_item[_item.Count]);
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerator<IStore> GetEnumerator()
|
||||
{
|
||||
foreach (NSOutlook.Store store in _item)
|
||||
{
|
||||
yield return Mapping.Wrap(store);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
foreach (NSOutlook.Store store in _item)
|
||||
{
|
||||
yield return Mapping.Wrap(store);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IAccount> Accounts
|
||||
{
|
||||
get
|
||||
{
|
||||
return _accountsBySmtp.Values;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Registry
|
||||
|
||||
/// <summary>
|
||||
/// Creates the AccountWrapper for the store, from the registry.
|
||||
/// </summary>
|
||||
/// <param name="store">The store. Ownership is transferred to the AccountWrapper. If the account is not created, the store is NOT disposed</param>
|
||||
/// <returns>The AccountWrapper, or null if no account is associated with the store</returns>
|
||||
private AccountWrapper TryCreateFromRegistry(IStore store)
|
||||
{
|
||||
using (RegistryKey baseKey = FindRegistryKey(store))
|
||||
{
|
||||
if (baseKey == null)
|
||||
return null;
|
||||
AccountWrapper account = new AccountWrapper(baseKey.Name, store);
|
||||
Register(account);
|
||||
return account;
|
||||
}
|
||||
}
|
||||
|
||||
private void Register(AccountWrapper account)
|
||||
{
|
||||
// Register the new account
|
||||
_accountsBySmtp.Add(account.SmtpAddress, account);
|
||||
_accountsByStoreId.Add(account.StoreID, account);
|
||||
Logger.Instance.Trace(this, "Account registered: {0} -> {1}", account.DisplayName, account.StoreID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the registry key for the account associated with the store.
|
||||
/// </summary>
|
||||
/// <returns>The registry key, or null if it cannot be found</returns>
|
||||
private RegistryKey FindRegistryKey(IStore store)
|
||||
{
|
||||
// Find the registry key by store id
|
||||
using (RegistryKey key = OpenBaseKey())
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
foreach (string subkey in key.GetSubKeyNames())
|
||||
{
|
||||
RegistryKey accountKey = key.OpenSubKey(subkey);
|
||||
string storeId = AccountWrapper.GetStoreId(accountKey.Name);
|
||||
if (storeId != null && storeId == store.StoreID)
|
||||
{
|
||||
return accountKey;
|
||||
}
|
||||
accountKey.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RegistryKey OpenBaseKey()
|
||||
{
|
||||
NSOutlook.NameSpace session = _item.Session;
|
||||
try
|
||||
{
|
||||
string path = string.Format(OutlookConstants.REG_SUBKEY_ACCOUNTS, session.CurrentProfileName);
|
||||
return OutlookRegistryUtils.OpenOutlookKey(path);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ComRelease.Release(session);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -95,9 +95,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
}
|
||||
}
|
||||
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
public IStore GetStore()
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
@ -105,9 +103,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
||||
return Mapping.Wrap(parent?.Store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StoreId
|
||||
public string StoreID
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -146,7 +146,10 @@ namespace Acacia
|
||||
|
||||
// Start watching events
|
||||
if (DebugOptions.GetOption(null, DebugOptions.WATCHER_ENABLED))
|
||||
{
|
||||
((AddInWrapper)Instance).Start();
|
||||
Watcher.Start();
|
||||
}
|
||||
|
||||
// Done
|
||||
Logger.Instance.Debug(this, "Startup done");
|
||||
|
@ -88,5 +88,44 @@ namespace Acacia.Utils
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Timers
|
||||
|
||||
public static void Delayed(LogContext log, int millis, System.Action action)
|
||||
{
|
||||
RegisterTimer(log, millis, action, false);
|
||||
}
|
||||
|
||||
public static void Timed(LogContext log, int millis, System.Action action)
|
||||
{
|
||||
RegisterTimer(log, millis, action, true);
|
||||
}
|
||||
|
||||
private static void RegisterTimer(LogContext log, int millis, System.Action action, bool repeat)
|
||||
{
|
||||
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
|
||||
timer.Interval = millis;
|
||||
timer.Tick += (s, eargs) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
if (!repeat)
|
||||
{
|
||||
timer.Enabled = false;
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Trace(log, "Exception in timer: {0}", e);
|
||||
}
|
||||
};
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -147,9 +147,9 @@ namespace Acacia.ZPush.Connect
|
||||
// TODO: it would be nice to let the system handle the SecureString for the password. However,
|
||||
// when specifying credentials for an HttpClient, they are only used after a 401 is received
|
||||
// on the first request, basically doubling the number of requests.
|
||||
using (SecureString pass = _account.Password)
|
||||
using (SecureString pass = _account.Account.Password)
|
||||
{
|
||||
var byteArray = Encoding.UTF8.GetBytes(_account.UserName + ":" + pass.ConvertToUnsecureString());
|
||||
var byteArray = Encoding.UTF8.GetBytes(_account.Account.UserName + ":" + pass.ConvertToUnsecureString());
|
||||
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
|
||||
_client.DefaultRequestHeaders.Authorization = header;
|
||||
}
|
||||
@ -278,8 +278,8 @@ namespace Acacia.ZPush.Connect
|
||||
|
||||
public Response Execute(ActiveSync.RequestBase request)
|
||||
{
|
||||
string url = string.Format(ACTIVESYNC_URL, _account.ServerURL, _account.DeviceId,
|
||||
request.Command, _account.UserName, "WindowsOutlook");
|
||||
string url = string.Format(ACTIVESYNC_URL, _account.Account.ServerURL, _account.Account.DeviceId,
|
||||
request.Command, _account.Account.UserName, "WindowsOutlook");
|
||||
|
||||
// Construct the body
|
||||
WBXMLDocument doc = new WBXMLDocument();
|
||||
@ -291,10 +291,10 @@ namespace Acacia.ZPush.Connect
|
||||
|
||||
using (HttpContent content = new ByteArrayContent(contentBody))
|
||||
{
|
||||
Logger.Instance.Trace(this, "Sending request: {0} -> {1}", _account.ServerURL, doc.ToXMLString());
|
||||
Logger.Instance.Trace(this, "Sending request: {0} -> {1}", _account.Account.ServerURL, doc.ToXMLString());
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-sync.wbxml");
|
||||
string caps = ZPushCapabilities.Client.ToString();
|
||||
Logger.Instance.Trace(this, "Sending request: {0} -> {1}: {2}", _account.ServerURL, caps, doc.ToXMLString());
|
||||
Logger.Instance.Trace(this, "Sending request: {0} -> {1}: {2}", _account.Account.ServerURL, caps, doc.ToXMLString());
|
||||
content.Headers.Add(Constants.ZPUSH_HEADER_CLIENT_CAPABILITIES, caps);
|
||||
using (HttpResponseMessage response = _client.PostAsync(url, content, _cancel).Result)
|
||||
{
|
||||
|
@ -46,14 +46,14 @@ namespace Acacia.ZPush.Connect
|
||||
public ResponseType Execute<ResponseType>(SoapRequest<ResponseType> request)
|
||||
{
|
||||
// Create the url
|
||||
string url = string.Format(ACTIVESYNC_URL, _connection.Account.ServerURL, "webservice",
|
||||
string url = string.Format(ACTIVESYNC_URL, _connection.Account.Account.ServerURL, "webservice",
|
||||
ServiceName,
|
||||
// TODO: this username is a bit of a quick hack.
|
||||
request.UserName ?? _connection.Account.UserName,
|
||||
request.UserName ?? _connection.Account.Account.UserName,
|
||||
"webservice");
|
||||
|
||||
// Set up the encoding
|
||||
SoapRequestEncoder encoder = new SoapRequestEncoder(_connection.Account.ServerURL, ServiceParameters, request);
|
||||
SoapRequestEncoder encoder = new SoapRequestEncoder(_connection.Account.Account.ServerURL, ServiceParameters, request);
|
||||
encoder.ServiceName = ServiceName;
|
||||
|
||||
// Execute the request
|
||||
@ -85,7 +85,7 @@ namespace Acacia.ZPush.Connect
|
||||
get
|
||||
{
|
||||
SoapParameters parameters = new SoapParameters();
|
||||
parameters.Add("devid", _connection.Account.DeviceId.ToLower());
|
||||
parameters.Add("devid", _connection.Account.Account.DeviceId.ToLower());
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
@ -32,143 +32,41 @@ using System.Threading.Tasks;
|
||||
namespace Acacia.ZPush
|
||||
{
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public class ZPushAccount : DisposableWrapper, LogContext
|
||||
public class ZPushAccount : LogContext
|
||||
{
|
||||
#region Miscellaneous
|
||||
|
||||
private readonly string _regPath;
|
||||
private readonly IAccount _account;
|
||||
|
||||
private readonly IStore _store;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="regPath">They registry key containing the account settings.</param>
|
||||
/// <param name="store">The store this account represents. The new object takes ownership</param>
|
||||
internal ZPushAccount(string regPath, IStore store)
|
||||
internal ZPushAccount(IAccount account)
|
||||
{
|
||||
this._regPath = regPath;
|
||||
this._store = store;
|
||||
|
||||
// Cache the SmtpAddress, it is used as the key
|
||||
SmtpAddress = RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EMAIL, null);
|
||||
this._account = account;
|
||||
}
|
||||
|
||||
protected override void DoRelease()
|
||||
{
|
||||
_store.Dispose();
|
||||
}
|
||||
[Browsable(false)]
|
||||
public IAccount Account { get { return _account; } }
|
||||
public String DisplayName { get { return _account.DisplayName; } }
|
||||
|
||||
[Browsable(false)]
|
||||
public string LogContextId
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ZPushAccount(" + SmtpAddress + ")";
|
||||
return "ZPushAccount(" + _account.SmtpAddress + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return SmtpAddress;
|
||||
return _account.SmtpAddress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers an Outlook send/receive operation.
|
||||
/// Triggers an Outlook send/receive operation for this account.
|
||||
/// </summary>
|
||||
public void SendReceive()
|
||||
{
|
||||
// TODO: ThisAddIn.Instance.SendReceive();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
[Browsable(false)]
|
||||
public IStore Store
|
||||
{
|
||||
get
|
||||
{
|
||||
return _store;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_DISPLAYNAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string SmtpAddress
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_USERNAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string ServerURL
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_SERVER, null);
|
||||
}
|
||||
}
|
||||
|
||||
public string DeviceId
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_DEVICEID, null);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public SecureString Password
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] encrypted = (byte[])Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null);
|
||||
return PasswordEncryption.Decrypt(encrypted);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public bool HasPassword
|
||||
{
|
||||
get { return Registry.GetValue(_regPath, OutlookConstants.REG_VAL_EAS_PASSWORD, null) != null; }
|
||||
}
|
||||
|
||||
public string StoreID
|
||||
{
|
||||
get { return GetStoreId(_regPath); }
|
||||
}
|
||||
|
||||
public static string GetStoreId(string regPath)
|
||||
{
|
||||
return StringUtil.BytesToHex((byte[])Registry.GetValue(regPath, OutlookConstants.REG_VAL_EAS_STOREID, null));
|
||||
}
|
||||
|
||||
public string DomainName
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = SmtpAddress.IndexOf('@');
|
||||
if (index < 0)
|
||||
return SmtpAddress;
|
||||
else
|
||||
return SmtpAddress.Substring(index + 1);
|
||||
}
|
||||
ThisAddIn.Instance.SendReceive(Account);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -23,21 +23,19 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.ZPush
|
||||
{
|
||||
/// <summary>
|
||||
/// Maintains the mapping from Outlook accounts to ZPush accounts, which
|
||||
/// provide additional functionality and workarounds.
|
||||
/// TODO: split into Outlook and Z-Push specific parts
|
||||
/// </summary>
|
||||
public class ZPushAccounts
|
||||
public class ZPushAccounts : DisposableWrapper
|
||||
{
|
||||
private readonly ZPushWatcher _watcher;
|
||||
// TODO: wrap these
|
||||
private readonly NSOutlook.Application _app;
|
||||
private readonly NSOutlook.NameSpace _session;
|
||||
private readonly NSOutlook.Stores _stores;
|
||||
private readonly IAddIn _addIn;
|
||||
private readonly IStores _stores;
|
||||
|
||||
/// <summary>
|
||||
/// ZPushAccounts indexed by SMTPAddress. Null values are not allowed.
|
||||
@ -45,351 +43,126 @@ namespace Acacia.ZPush
|
||||
private readonly Dictionary<string, ZPushAccount> _accountsBySmtp = new Dictionary<string, ZPushAccount>();
|
||||
|
||||
/// <summary>
|
||||
/// ZPushAccounts indexed by store id. Null values are allowed, if a store has been
|
||||
/// determined to not be associated with a ZPushAccount. This is required to determine when a store is new.
|
||||
/// ZPushAccounts indexed by store id. Null values are noy allowed.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, ZPushAccount> _accountsByStoreId = new Dictionary<string, ZPushAccount>();
|
||||
|
||||
public ZPushAccounts(ZPushWatcher watcher, NSOutlook.Application app)
|
||||
public ZPushAccounts(ZPushWatcher watcher, IAddIn addIn)
|
||||
{
|
||||
this._watcher = watcher;
|
||||
this._app = app;
|
||||
this._session = app.Session;
|
||||
this._stores = _session.Stores;
|
||||
this._addIn = addIn;
|
||||
this._stores = addIn.Stores;
|
||||
}
|
||||
|
||||
internal void Start()
|
||||
protected override void DoRelease()
|
||||
{
|
||||
// Register for new stores
|
||||
// The store remove event is not sent, so don't register for that
|
||||
_stores.StoreAdd += StoreAdded;
|
||||
_stores.Dispose();
|
||||
}
|
||||
|
||||
#region Implementation
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (GlobalOptions.INSTANCE.ZPushCheck)
|
||||
{
|
||||
// Process existing accounts
|
||||
using (ComRelease com = new ComRelease())
|
||||
foreach (NSOutlook.Account account in com.Add(_session.Accounts))
|
||||
foreach (IAccount account in _stores.Accounts)
|
||||
{
|
||||
Tasks.Task(null, "AccountCheck", () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: check if EAS account
|
||||
// account gets released by GetAccount, save DisplayName for log purposes.
|
||||
string displayName = account.DisplayName;
|
||||
Logger.Instance.Trace(this, "Checking account: {0}", displayName);
|
||||
ZPushAccount zpush = GetAccount(account);
|
||||
if (zpush == null)
|
||||
{
|
||||
Logger.Instance.Trace(this, "Not a ZPush account: {0}", displayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Instance.Trace(this, "ZPush account: {0}", zpush);
|
||||
_watcher.OnAccountDiscovered(zpush, true);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "Exception processing account: {0}", e);
|
||||
}
|
||||
AccountAdded(account);
|
||||
});
|
||||
}
|
||||
|
||||
Tasks.Task(null, "AccountCheckDone", () =>
|
||||
{
|
||||
_watcher.OnAccountsScanned();
|
||||
|
||||
if (GlobalOptions.INSTANCE.AccountTimer)
|
||||
{
|
||||
// Set up timer to check for removed accounts
|
||||
_watcher.Timed(Config.ACCOUNT_CHECK_INTERVAL, CheckAccountsRemoved);
|
||||
}
|
||||
});
|
||||
|
||||
// Register for account changes
|
||||
_stores.AccountDiscovered += AccountAdded;
|
||||
_stores.AccountRemoved += AccountRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAccountsRemoved()
|
||||
private void AccountAdded(IAccount account)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Collect all the store ids
|
||||
HashSet<string> stores = new HashSet<string>();
|
||||
foreach (NSOutlook.Store store in _stores)
|
||||
Logger.Instance.Trace(this, "Checking account: {0}", account);
|
||||
|
||||
// Only EAS accounts can be zpush accounts
|
||||
if (account.AccountType == AccountType.EAS)
|
||||
{
|
||||
try
|
||||
{
|
||||
stores.Add(store.StoreID);
|
||||
ZPushAccount zpush = new ZPushAccount(account);
|
||||
_accountsByStoreId.Add(account.StoreID, zpush);
|
||||
_accountsBySmtp.Add(account.SmtpAddress, zpush);
|
||||
Logger.Instance.Trace(this, "ZPush account: {0}", zpush);
|
||||
_watcher.OnAccountDiscovered(zpush);
|
||||
}
|
||||
finally
|
||||
else
|
||||
{
|
||||
ComRelease.Release(store);
|
||||
Logger.Instance.Trace(this, "Not a ZPush account: {0}", account);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "Exception processing account: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any relevant ones are removed
|
||||
List<KeyValuePair<string, ZPushAccount>> removed = new List<KeyValuePair<string, ZPushAccount>>();
|
||||
foreach(KeyValuePair<string, ZPushAccount> account in _accountsByStoreId)
|
||||
private void AccountRemoved(IAccount account)
|
||||
{
|
||||
if (!stores.Contains(account.Key))
|
||||
{
|
||||
Logger.Instance.Trace(this, "Store not found: {0} - {1}", account.Value, account.Key);
|
||||
removed.Add(account);
|
||||
}
|
||||
_accountsBySmtp.Remove(account.SmtpAddress);
|
||||
_accountsByStoreId.Remove(account.StoreID);
|
||||
}
|
||||
|
||||
// Process any removed stores
|
||||
foreach(KeyValuePair<string, ZPushAccount> remove in removed)
|
||||
{
|
||||
Logger.Instance.Debug(this, "Account removed: {0} - {1}", remove.Value, remove.Key);
|
||||
_accountsBySmtp.Remove(remove.Value.SmtpAddress);
|
||||
_accountsByStoreId.Remove(remove.Key);
|
||||
_watcher.OnAccountRemoved(remove.Value);
|
||||
}
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "Exception in CheckAccountsRemoved: {0}", e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public IEnumerable<ZPushAccount> GetAccounts()
|
||||
{
|
||||
return _accountsBySmtp.Values;
|
||||
}
|
||||
#region Account access
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ZPushAccount on which the folder is located.
|
||||
/// </summary>
|
||||
/// <returns>The ZPushAccount, or null if the folder is not on a zpush account</returns>
|
||||
public ZPushAccount GetAccount(IFolder folder)
|
||||
{
|
||||
ZPushAccount zpush = null;
|
||||
using (IStore store = folder.Store)
|
||||
_accountsByStoreId.TryGetValue(store.StoreID, out zpush);
|
||||
return zpush;
|
||||
}
|
||||
public ZPushAccount GetAccount(IStore store)
|
||||
{
|
||||
ZPushAccount zpush = null;
|
||||
_accountsByStoreId.TryGetValue(store.StoreID, out zpush);
|
||||
return zpush;
|
||||
}
|
||||
public ZPushAccount GetAccount(IBase item)
|
||||
{
|
||||
if (item is IFolder)
|
||||
return GetAccount((IFolder)item);
|
||||
else if (item is IStore)
|
||||
return GetAccount((IStore)item);
|
||||
if (item.Parent != null)
|
||||
return GetAccount(item.Parent);
|
||||
return null;
|
||||
ZPushAccount value = null;
|
||||
_accountsByStoreId.TryGetValue(folder.StoreID, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public ZPushAccount GetAccount(NSOutlook.MAPIFolder folder)
|
||||
public ZPushAccount GetAccount(IAccount account)
|
||||
{
|
||||
using (ComRelease com = new ComRelease())
|
||||
{
|
||||
ZPushAccount zpush = null;
|
||||
NSOutlook.Store store = com.Add(folder.Store);
|
||||
string storeId = store?.StoreID;
|
||||
if (storeId == null)
|
||||
return null;
|
||||
_accountsByStoreId.TryGetValue(storeId, out zpush);
|
||||
return zpush;
|
||||
ZPushAccount value = null;
|
||||
_accountsByStoreId.TryGetValue(account.StoreID, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public ZPushAccount GetAccount(IStore store)
|
||||
{
|
||||
ZPushAccount value = null;
|
||||
_accountsByStoreId.TryGetValue(store.StoreID, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public ZPushAccount GetAccount(IBase obj)
|
||||
{
|
||||
if (obj is IFolder)
|
||||
return GetAccount((IFolder)obj);
|
||||
else if (obj is IStore)
|
||||
return GetAccount((IStore)obj);
|
||||
if (obj.Parent != null)
|
||||
return GetAccount(obj.Parent);
|
||||
return null;
|
||||
}
|
||||
|
||||
public ZPushAccount GetAccount(string smtpAddress)
|
||||
{
|
||||
ZPushAccount account = null;
|
||||
_accountsBySmtp.TryGetValue(smtpAddress, out account);
|
||||
return account;
|
||||
ZPushAccount value = null;
|
||||
_accountsBySmtp.TryGetValue(smtpAddress, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ZPush account associated with the Outlook account.
|
||||
/// </summary>
|
||||
/// <param name="account">The account. This function will release the handle</param>
|
||||
/// <returns>The ZPushAccount, or null if not a ZPush account.</returns>
|
||||
private ZPushAccount GetAccount(NSOutlook.Account account)
|
||||
public IEnumerable<ZPushAccount> GetAccounts()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Only EAS accounts can be zpush accounts
|
||||
if (account.AccountType != NSOutlook.OlAccountType.olEas)
|
||||
return null;
|
||||
|
||||
// Check for a cached value
|
||||
ZPushAccount zpush;
|
||||
if (_accountsBySmtp.TryGetValue(account.SmtpAddress, out zpush))
|
||||
return zpush;
|
||||
|
||||
// Create a new account
|
||||
return CreateFromRegistry(account);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ComRelease.Release(account);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for Stores.StoreAdded event.
|
||||
/// </summary>
|
||||
private void StoreAdded(NSOutlook.Store s)
|
||||
{
|
||||
IStore store = null;
|
||||
try
|
||||
{
|
||||
// Accessing the store object causes random crashes, simply iterate to find new stores
|
||||
Logger.Instance.Trace(this, "StoreAdded: {0}", s.StoreID);
|
||||
foreach (NSOutlook.Store rawStore in _session.Stores.RawEnum(false))
|
||||
{
|
||||
if (!_accountsByStoreId.ContainsKey(rawStore.StoreID))
|
||||
{
|
||||
Logger.Instance.Trace(this, "New store: {0}", rawStore.DisplayName);
|
||||
|
||||
store = Mapping.Wrap(rawStore);
|
||||
ZPushAccount zpush = TryCreateFromRegistry(store);
|
||||
if (zpush == null)
|
||||
{
|
||||
// Add it to the cache so it is not evaluated again.
|
||||
_accountsByStoreId.Add(store.StoreID, null);
|
||||
Logger.Instance.Trace(this, "Not a ZPush store: {0}", store.DisplayName);
|
||||
store.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Instance.Trace(this, "New ZPush store: {0}: {1}", store.DisplayName, zpush);
|
||||
_watcher.OnAccountDiscovered(zpush, false);
|
||||
// zpush has taken ownership
|
||||
}
|
||||
}
|
||||
else ComRelease.Release(rawStore);
|
||||
}
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
Logger.Instance.Error(this, "StoreAdded Exception: {0}", e);
|
||||
if (store != null)
|
||||
store.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#region Registry
|
||||
|
||||
private void Register(ZPushAccount zpush)
|
||||
{
|
||||
// Register the new account
|
||||
_accountsBySmtp.Add(zpush.SmtpAddress, zpush);
|
||||
_accountsByStoreId.Add(zpush.StoreID, zpush);
|
||||
Logger.Instance.Trace(this, "Account registered: {0} -> {1}", zpush.DisplayName, zpush.Store.StoreID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the ZPushAccount for the account, from the registry values.
|
||||
/// </summary>
|
||||
/// <param name="account">The account. The caller is responsible for releasing this.</param>
|
||||
/// <returns>The associated ZPushAccount</returns>
|
||||
/// <exception cref="Exception">If the registry key cannot be found</exception>
|
||||
// TODO: check owner
|
||||
private ZPushAccount CreateFromRegistry(NSOutlook.Account account)
|
||||
{
|
||||
// TODO: check that caller releases account everywhere
|
||||
using (ComRelease com = new ComRelease())
|
||||
using (RegistryKey baseKey = FindRegistryKey(account))
|
||||
{
|
||||
if (baseKey == null)
|
||||
throw new System.Exception("Unknown account: " + account.SmtpAddress);
|
||||
|
||||
// Get the store id
|
||||
string storeId = ZPushAccount.GetStoreId(baseKey.Name);
|
||||
|
||||
// Find the store
|
||||
NSOutlook.Store store = _session.GetStoreFromID(storeId);
|
||||
|
||||
// Done, create and register
|
||||
ZPushAccount zpush = new ZPushAccount(baseKey.Name, Mapping.Wrap(store));
|
||||
Register(zpush);
|
||||
return zpush;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the ZPushAccount for the store, from the registry.
|
||||
/// </summary>
|
||||
/// <param name="store">The store. Ownership is transferred to the ZPushAccount. If the account is not created, the store is NOT disposed</param>
|
||||
/// <returns>The ZPushAccount, or null if no account is associated with the store</returns>
|
||||
private ZPushAccount TryCreateFromRegistry(IStore store)
|
||||
{
|
||||
using (RegistryKey baseKey = FindRegistryKey(store))
|
||||
{
|
||||
if (baseKey == null)
|
||||
return null;
|
||||
ZPushAccount zpush = new ZPushAccount(baseKey.Name, store);
|
||||
Register(zpush);
|
||||
return zpush;
|
||||
}
|
||||
}
|
||||
|
||||
private RegistryKey OpenBaseKey()
|
||||
{
|
||||
NSOutlook.NameSpace session = _app.Session;
|
||||
string path = string.Format(OutlookConstants.REG_SUBKEY_ACCOUNTS, session.CurrentProfileName);
|
||||
ComRelease.Release(session);
|
||||
return OutlookRegistryUtils.OpenOutlookKey(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the registry key for the account.
|
||||
/// </summary>
|
||||
/// <returns>The registry key, or null if it cannot be found</returns>
|
||||
private RegistryKey FindRegistryKey(NSOutlook.Account account)
|
||||
{
|
||||
// Find the registry key by email adddress
|
||||
using (RegistryKey key = OpenBaseKey())
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
foreach (string subkey in key.GetSubKeyNames())
|
||||
{
|
||||
RegistryKey accountKey = key.OpenSubKey(subkey);
|
||||
if (accountKey.GetValueString(OutlookConstants.REG_VAL_EMAIL) == account.SmtpAddress)
|
||||
{
|
||||
return accountKey;
|
||||
}
|
||||
accountKey.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the registry key for the account associated with the store.
|
||||
/// </summary>
|
||||
/// <returns>The registry key, or null if it cannot be found</returns>
|
||||
private RegistryKey FindRegistryKey(IStore store)
|
||||
{
|
||||
// Find the registry key by store id
|
||||
using (RegistryKey key = OpenBaseKey())
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
foreach (string subkey in key.GetSubKeyNames())
|
||||
{
|
||||
RegistryKey accountKey = key.OpenSubKey(subkey);
|
||||
string storeId = ZPushAccount.GetStoreId(accountKey.Name);
|
||||
if (storeId != null && storeId == store.StoreID)
|
||||
{
|
||||
return accountKey;
|
||||
}
|
||||
accountKey.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return _accountsByStoreId.Values;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -23,7 +23,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Acacia.ZPush
|
||||
{
|
||||
@ -88,7 +87,7 @@ namespace Acacia.ZPush
|
||||
|
||||
// Path found, create the store
|
||||
Logger.Instance.Info(typeof(ZPushLocalStore), "Creating new store: {0}", path);
|
||||
store = addIn.AddFileStore(path);
|
||||
store = addIn.Stores.AddFileStore(path);
|
||||
Logger.Instance.Debug(typeof(ZPushLocalStore), "Created new store: {0}", store.FilePath);
|
||||
|
||||
// Set the display name
|
||||
|
@ -53,7 +53,7 @@ namespace Acacia.ZPush
|
||||
this._addIn = addIn;
|
||||
this._app = addIn.RawApp;
|
||||
Sync = new ZPushSync(this, addIn);
|
||||
Accounts = new ZPushAccounts(this, _app);
|
||||
Accounts = new ZPushAccounts(this, addIn);
|
||||
|
||||
// Need to keep a link to keep receiving events
|
||||
_explorer2 = _app.ActiveExplorer();
|
||||
@ -77,43 +77,6 @@ namespace Acacia.ZPush
|
||||
|
||||
#endregion
|
||||
|
||||
#region Timers
|
||||
|
||||
public void Delayed(int millis, System.Action action)
|
||||
{
|
||||
RegisterTimer(millis, action, false);
|
||||
}
|
||||
|
||||
public void Timed(int millis, System.Action action)
|
||||
{
|
||||
RegisterTimer(millis, action, true);
|
||||
}
|
||||
|
||||
private void RegisterTimer(int millis, System.Action action, bool repeat)
|
||||
{
|
||||
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
|
||||
timer.Interval = millis;
|
||||
timer.Tick += (s, eargs) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
if (!repeat)
|
||||
{
|
||||
timer.Enabled = false;
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
Logger.Instance.Trace(this, "Exception in timer: {0}", e);
|
||||
}
|
||||
};
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accounts
|
||||
|
||||
public delegate void AccountHandler(ZPushAccount account);
|
||||
@ -134,18 +97,15 @@ namespace Acacia.ZPush
|
||||
/// Handles a new account.
|
||||
/// </summary>
|
||||
/// <param name="account">The account.</param>
|
||||
/// <param name="isExisting">True if the account is an existing account, false if
|
||||
/// it is a new account</param>
|
||||
internal void OnAccountDiscovered(ZPushAccount account, bool isExisting)
|
||||
internal void OnAccountDiscovered(ZPushAccount account)
|
||||
{
|
||||
// Notify any account listeners
|
||||
if (AccountDiscovered != null)
|
||||
AccountDiscovered(account);
|
||||
AccountDiscovered?.Invoke(account);
|
||||
|
||||
// Register any events
|
||||
HandleFolderWatchers(account);
|
||||
|
||||
if (account.HasPassword)
|
||||
if (account.Account.HasPassword)
|
||||
{
|
||||
// Send an OOF request to get the OOF state and capabilities
|
||||
Tasks.Task(null, "ZPushCheck: " + account.DisplayName, () =>
|
||||
@ -274,7 +234,7 @@ namespace Acacia.ZPush
|
||||
private void HandleFolderWatchers(ZPushAccount account)
|
||||
{
|
||||
// We need to keep the object alive to keep receiving events
|
||||
_rootFolder = new ZPushFolder(this, account.Store.GetRootFolder());
|
||||
_rootFolder = new ZPushFolder(this, account.Account.Store.GetRootFolder());
|
||||
}
|
||||
|
||||
public void WatchFolder(FolderRegistration folder, FolderEventHandler handler, FolderEventHandler changedHandler = null)
|
||||
@ -367,7 +327,7 @@ namespace Acacia.ZPush
|
||||
|
||||
string entryId = folder.EntryID;
|
||||
|
||||
using (IStore store = folder.Store)
|
||||
using (IStore store = folder.GetStore())
|
||||
{
|
||||
foreach(DefaultFolder defaultFolderId in BLACKLISTED_MAIL_FOLDERS)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user