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="Native\IOleWindow.cs" />
|
||||||
<Compile Include="OutlookConstants.cs" />
|
<Compile Include="OutlookConstants.cs" />
|
||||||
<Compile Include="Stubs\Enums.cs" />
|
<Compile Include="Stubs\Enums.cs" />
|
||||||
|
<Compile Include="Stubs\IAccount.cs" />
|
||||||
<Compile Include="Stubs\IAddIn.cs" />
|
<Compile Include="Stubs\IAddIn.cs" />
|
||||||
<Compile Include="Stubs\IAddressEntry.cs" />
|
<Compile Include="Stubs\IAddressEntry.cs" />
|
||||||
<Compile Include="Stubs\ICommandBars.cs" />
|
<Compile Include="Stubs\ICommandBars.cs" />
|
||||||
@ -288,7 +289,9 @@
|
|||||||
<Compile Include="Stubs\IItemEvents.cs" />
|
<Compile Include="Stubs\IItemEvents.cs" />
|
||||||
<Compile Include="Stubs\IOutlookWindow.cs" />
|
<Compile Include="Stubs\IOutlookWindow.cs" />
|
||||||
<Compile Include="Stubs\IRecipient.cs" />
|
<Compile Include="Stubs\IRecipient.cs" />
|
||||||
|
<Compile Include="Stubs\IStores.cs" />
|
||||||
<Compile Include="Stubs\ISyncObject.cs" />
|
<Compile Include="Stubs\ISyncObject.cs" />
|
||||||
|
<Compile Include="Stubs\OutlookWrappers\AccountWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
|
||||||
@ -296,6 +299,7 @@
|
|||||||
<Compile Include="Stubs\OutlookWrappers\ItemEventsWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\ItemEventsWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\OutlookItemWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\OutlookItemWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" />
|
||||||
|
<Compile Include="Stubs\OutlookWrappers\StoresWrapper.cs" />
|
||||||
<Compile Include="Stubs\OutlookWrappers\SyncObjectWrapper.cs" />
|
<Compile Include="Stubs\OutlookWrappers\SyncObjectWrapper.cs" />
|
||||||
<Compile Include="Stubs\Wrappers.cs" />
|
<Compile Include="Stubs\Wrappers.cs" />
|
||||||
<Compile Include="UI\Outlook\OutlookImageList.cs" />
|
<Compile Include="UI\Outlook\OutlookImageList.cs" />
|
||||||
|
@ -103,7 +103,7 @@ namespace Acacia.Features.FreeBusy
|
|||||||
|
|
||||||
set
|
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 System.Windows.Forms;
|
||||||
using Acacia.UI;
|
using Acacia.UI;
|
||||||
using static Acacia.DebugOptions;
|
using static Acacia.DebugOptions;
|
||||||
using Microsoft.Office.Interop.Outlook;
|
|
||||||
|
|
||||||
namespace Acacia.Features.GAB
|
namespace Acacia.Features.GAB
|
||||||
{
|
{
|
||||||
@ -474,7 +473,7 @@ namespace Acacia.Features.GAB
|
|||||||
private void AccountDiscovered(ZPushAccount zpush)
|
private void AccountDiscovered(ZPushAccount zpush)
|
||||||
{
|
{
|
||||||
Logger.Instance.Info(this, "Account discovered: {0}", zpush.DisplayName);
|
Logger.Instance.Info(this, "Account discovered: {0}", zpush.DisplayName);
|
||||||
_domains.Add(zpush.DomainName);
|
_domains.Add(zpush.Account.DomainName);
|
||||||
|
|
||||||
zpush.ConfirmedChanged += (z) =>
|
zpush.ConfirmedChanged += (z) =>
|
||||||
{
|
{
|
||||||
@ -606,7 +605,7 @@ namespace Acacia.Features.GAB
|
|||||||
private void RegisterGABAccount(ZPushAccount account, IFolder folder)
|
private void RegisterGABAccount(ZPushAccount account, IFolder folder)
|
||||||
{
|
{
|
||||||
// Determine the domain name
|
// 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
|
// Could already be registered if there are multiple accounts on the same domain
|
||||||
GABHandler gab;
|
GABHandler gab;
|
||||||
@ -637,7 +636,7 @@ namespace Acacia.Features.GAB
|
|||||||
|
|
||||||
private void ZPushChannelAvailable(IFolder folder)
|
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);
|
Logger.Instance.Debug(this, "Z-Push channel available: {0} on {1}", folder, store.DisplayName);
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace Acacia.Features.GAB
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
using(IStore store = Folder.Store)
|
using(IStore store = Folder.GetStore())
|
||||||
return store.DisplayName;
|
return store.DisplayName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ namespace Acacia.Features.OutOfOffice
|
|||||||
if (oof.State != ActiveSync.OOFState.Disabled)
|
if (oof.State != ActiveSync.OOFState.Disabled)
|
||||||
{
|
{
|
||||||
if (MessageBox.Show(
|
if (MessageBox.Show(
|
||||||
string.Format(Properties.Resources.OOFStartup_Message, account.SmtpAddress),
|
string.Format(Properties.Resources.OOFStartup_Message, account.Account.SmtpAddress),
|
||||||
Properties.Resources.OOFStartup_Title,
|
Properties.Resources.OOFStartup_Title,
|
||||||
MessageBoxButtons.YesNo,
|
MessageBoxButtons.YesNo,
|
||||||
MessageBoxIcon.Question
|
MessageBoxIcon.Question
|
||||||
|
@ -43,7 +43,7 @@ namespace Acacia.Features.OutOfOffice
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
// Add the email address to the title
|
// Add the email address to the title
|
||||||
Text = string.Format(Text, account.SmtpAddress);
|
Text = string.Format(Text, account.Account.SmtpAddress);
|
||||||
|
|
||||||
// Set the time formats
|
// Set the time formats
|
||||||
timeFrom.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern;
|
timeFrom.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern;
|
||||||
|
@ -71,7 +71,7 @@ namespace Acacia.Features.SendAs
|
|||||||
private void MailEvents_Respond(IMailItem mail, IMailItem response)
|
private void MailEvents_Respond(IMailItem mail, IMailItem response)
|
||||||
{
|
{
|
||||||
Logger.Instance.Trace(this, "Responding to mail, checking");
|
Logger.Instance.Trace(this, "Responding to mail, checking");
|
||||||
using (IStore store = mail.Store)
|
using (IStore store = mail.GetStore())
|
||||||
{
|
{
|
||||||
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
|
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
|
||||||
Logger.Instance.Trace(this, "Checking ZPush: {0}", zpush);
|
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)
|
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);
|
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
|
||||||
if (zpush != null)
|
if (zpush != null)
|
||||||
{
|
{
|
||||||
string address = item.SenderEmailAddress;
|
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);
|
Logger.Instance.Trace(this, "SendAs: {0}: {1}", address, item.SenderName);
|
||||||
item.SetProperty(Constants.ZPUSH_SEND_AS, address);
|
item.SetProperty(Constants.ZPUSH_SEND_AS, address);
|
||||||
|
@ -71,7 +71,7 @@ namespace Acacia.Features.SharedFolders
|
|||||||
).Images;
|
).Images;
|
||||||
|
|
||||||
// Add the email address to the title
|
// Add the email address to the title
|
||||||
Text = string.Format(Text, account.SmtpAddress);
|
Text = string.Format(Text, account.Account.SmtpAddress);
|
||||||
|
|
||||||
// Set up options
|
// Set up options
|
||||||
ShowOptions(new KTreeNode[0]);
|
ShowOptions(new KTreeNode[0]);
|
||||||
|
@ -100,15 +100,15 @@ namespace Acacia.Features.WebApp
|
|||||||
// Perform a cached auto discover
|
// Perform a cached auto discover
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(this, "Starting kdiscover: {0}", account.DomainName);
|
Logger.Instance.Debug(this, "Starting kdiscover: {0}", account.Account.DomainName);
|
||||||
string url = PerformAutoDiscover(account);
|
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));
|
account.SetFeatureData(this, TXT_KDISCOVER, new URLCached(url));
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
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);
|
account.SetFeatureData(this, TXT_KDISCOVER, null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ namespace Acacia.Features.WebApp
|
|||||||
private string PerformAutoDiscover(ZPushAccount account)
|
private string PerformAutoDiscover(ZPushAccount account)
|
||||||
{
|
{
|
||||||
// Fetch the txt record
|
// Fetch the txt record
|
||||||
IList<string> txt = DnsUtil.GetTxtRecord(account.DomainName);
|
IList<string> txt = DnsUtil.GetTxtRecord(account.Account.DomainName);
|
||||||
if (txt == null)
|
if (txt == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -45,4 +45,11 @@ namespace Acacia.Stubs
|
|||||||
ManagedEmail = 29,
|
ManagedEmail = 29,
|
||||||
SuggestedContacts = 30
|
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
|
// TODO: clean this up
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends and receives all accounts.
|
/// Sends and receives all accounts, or a specific account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SendReceive();
|
void SendReceive(IAccount account = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Restarts the application
|
/// Restarts the application
|
||||||
@ -63,12 +63,13 @@ namespace Acacia.Stubs
|
|||||||
|
|
||||||
IRecipient ResolveRecipient(string name);
|
IRecipient ResolveRecipient(string name);
|
||||||
|
|
||||||
IStore AddFileStore(string path);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
IEnumerable<IStore> Stores { get; }
|
IStores Stores
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -42,14 +42,13 @@ namespace Acacia.Stubs
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the store. The owner is responsible for disposing.
|
/// Returns the store. The owner is responsible for disposing.
|
||||||
/// TODO: make method to make disposing clear
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IStore Store { get; }
|
IStore GetStore();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Quick accessor to Store.Id, to prevent allocating a wrapper for it.
|
/// Quick accessor to Store.Id, to prevent allocating a wrapper for it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string StoreId { get; }
|
string StoreID { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Quick accessor to Store.DisplayName, to prevent allocating a wrapper for it.
|
/// 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.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
using NSOutlookDelegates = Microsoft.Office.Interop.Outlook;
|
||||||
|
|
||||||
namespace Acacia.Stubs
|
namespace Acacia.Stubs
|
||||||
{
|
{
|
||||||
@ -12,32 +12,32 @@ namespace Acacia.Stubs
|
|||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
// TODO: custom delegates
|
// TODO: custom delegates
|
||||||
event NSOutlook.ItemEvents_10_AfterWriteEventHandler AfterWrite;
|
event NSOutlookDelegates.ItemEvents_10_AfterWriteEventHandler AfterWrite;
|
||||||
event NSOutlook.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
|
event NSOutlookDelegates.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
|
||||||
event NSOutlook.ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
|
event NSOutlookDelegates.ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
|
||||||
event NSOutlook.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
|
event NSOutlookDelegates.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
|
||||||
event NSOutlook.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
|
event NSOutlookDelegates.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
|
||||||
event NSOutlook.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
|
event NSOutlookDelegates.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
|
||||||
event NSOutlook.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
|
event NSOutlookDelegates.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
|
||||||
event NSOutlook.ItemEvents_10_BeforeReadEventHandler BeforeRead;
|
event NSOutlookDelegates.ItemEvents_10_BeforeReadEventHandler BeforeRead;
|
||||||
event NSOutlook.ItemEvents_10_CloseEventHandler Close;
|
event NSOutlookDelegates.ItemEvents_10_CloseEventHandler Close;
|
||||||
event NSOutlook.ItemEvents_10_CustomActionEventHandler CustomAction;
|
event NSOutlookDelegates.ItemEvents_10_CustomActionEventHandler CustomAction;
|
||||||
event NSOutlook.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
|
event NSOutlookDelegates.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
|
||||||
event NSOutlook.ItemEvents_10_ForwardEventHandler Forward;
|
event NSOutlookDelegates.ItemEvents_10_ForwardEventHandler Forward;
|
||||||
event NSOutlook.ItemEvents_10_OpenEventHandler Open;
|
event NSOutlookDelegates.ItemEvents_10_OpenEventHandler Open;
|
||||||
event NSOutlook.ItemEvents_10_PropertyChangeEventHandler PropertyChange;
|
event NSOutlookDelegates.ItemEvents_10_PropertyChangeEventHandler PropertyChange;
|
||||||
event NSOutlook.ItemEvents_10_ReadEventHandler Read;
|
event NSOutlookDelegates.ItemEvents_10_ReadEventHandler Read;
|
||||||
event NSOutlook.ItemEvents_10_ReadCompleteEventHandler ReadComplete;
|
event NSOutlookDelegates.ItemEvents_10_ReadCompleteEventHandler ReadComplete;
|
||||||
event NSOutlook.ItemEvents_10_ReplyEventHandler Reply;
|
event NSOutlookDelegates.ItemEvents_10_ReplyEventHandler Reply;
|
||||||
event NSOutlook.ItemEvents_10_ReplyAllEventHandler ReplyAll;
|
event NSOutlookDelegates.ItemEvents_10_ReplyAllEventHandler ReplyAll;
|
||||||
event NSOutlook.ItemEvents_10_SendEventHandler Send;
|
event NSOutlookDelegates.ItemEvents_10_SendEventHandler Send;
|
||||||
event NSOutlook.ItemEvents_10_UnloadEventHandler Unload;
|
event NSOutlookDelegates.ItemEvents_10_UnloadEventHandler Unload;
|
||||||
event NSOutlook.ItemEvents_10_WriteEventHandler Write;
|
event NSOutlookDelegates.ItemEvents_10_WriteEventHandler Write;
|
||||||
|
|
||||||
#endregion
|
#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.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
using NSOutlookDelegates = Microsoft.Office.Interop.Outlook;
|
||||||
|
|
||||||
namespace Acacia.Stubs
|
namespace Acacia.Stubs
|
||||||
{
|
{
|
||||||
@ -25,10 +25,10 @@ namespace Acacia.Stubs
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
// TODO: custom delegates
|
// TODO: custom delegates
|
||||||
event NSOutlook.SyncObjectEvents_OnErrorEventHandler OnError;
|
event NSOutlookDelegates.SyncObjectEvents_OnErrorEventHandler OnError;
|
||||||
event NSOutlook.SyncObjectEvents_ProgressEventHandler Progress;
|
event NSOutlookDelegates.SyncObjectEvents_ProgressEventHandler Progress;
|
||||||
event NSOutlook.SyncObjectEvents_SyncEndEventHandler SyncEnd;
|
event NSOutlookDelegates.SyncObjectEvents_SyncEndEventHandler SyncEnd;
|
||||||
event NSOutlook.SyncObjectEvents_SyncStartEventHandler SyncStart;
|
event NSOutlookDelegates.SyncObjectEvents_SyncStartEventHandler SyncStart;
|
||||||
#endregion
|
#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
|
public class AddInWrapper : IAddIn
|
||||||
{
|
{
|
||||||
|
private readonly NSOutlook.Application _app;
|
||||||
private readonly ThisAddIn _thisAddIn;
|
private readonly ThisAddIn _thisAddIn;
|
||||||
private NSOutlook.Application _app;
|
private readonly StoresWrapper _stores;
|
||||||
|
|
||||||
public AddInWrapper(ThisAddIn thisAddIn)
|
public AddInWrapper(ThisAddIn thisAddIn)
|
||||||
{
|
{
|
||||||
this._thisAddIn = thisAddIn;
|
this._thisAddIn = thisAddIn;
|
||||||
this._app = thisAddIn.Application;
|
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;
|
NSOutlook.NameSpace session = _app.Session;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -39,6 +51,11 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_stores.Start();
|
||||||
|
}
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
{
|
{
|
||||||
// Can not use the assembly location, as that is in the GAC
|
// 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())
|
get { return _stores; }
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,9 +116,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -126,9 +124,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -241,9 +241,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -251,9 +249,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -257,9 +257,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -267,9 +265,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -100,13 +100,13 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
|
|
||||||
public string EntryID { get { return _item.EntryID; } }
|
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
|
get
|
||||||
{
|
{
|
||||||
using (IStore store = Store)
|
using (IStore store = GetStore())
|
||||||
{
|
{
|
||||||
return store.StoreID;
|
return store.StoreID;
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
using (IStore store = Store)
|
using (IStore store = GetStore())
|
||||||
{
|
{
|
||||||
return store.DisplayName;
|
return store.DisplayName;
|
||||||
}
|
}
|
||||||
@ -241,7 +241,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStore store = Store)
|
using (IStore store = GetStore())
|
||||||
{
|
{
|
||||||
return store.GetItemFromID(entryId);
|
return store.GetItemFromID(entryId);
|
||||||
}
|
}
|
||||||
|
@ -150,9 +150,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -160,9 +158,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -97,9 +97,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -107,9 +105,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -95,9 +95,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStore Store
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -105,9 +103,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
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
|
public IStore GetStore()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
using (ComRelease com = new ComRelease())
|
||||||
{
|
{
|
||||||
@ -105,9 +103,8 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return Mapping.Wrap(parent?.Store);
|
return Mapping.Wrap(parent?.Store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string StoreId
|
public string StoreID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,10 @@ namespace Acacia
|
|||||||
|
|
||||||
// Start watching events
|
// Start watching events
|
||||||
if (DebugOptions.GetOption(null, DebugOptions.WATCHER_ENABLED))
|
if (DebugOptions.GetOption(null, DebugOptions.WATCHER_ENABLED))
|
||||||
|
{
|
||||||
|
((AddInWrapper)Instance).Start();
|
||||||
Watcher.Start();
|
Watcher.Start();
|
||||||
|
}
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
Logger.Instance.Debug(this, "Startup done");
|
Logger.Instance.Debug(this, "Startup done");
|
||||||
|
@ -88,5 +88,44 @@ namespace Acacia.Utils
|
|||||||
GC.WaitForPendingFinalizers();
|
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,
|
// 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
|
// 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.
|
// 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));
|
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
|
||||||
_client.DefaultRequestHeaders.Authorization = header;
|
_client.DefaultRequestHeaders.Authorization = header;
|
||||||
}
|
}
|
||||||
@ -278,8 +278,8 @@ namespace Acacia.ZPush.Connect
|
|||||||
|
|
||||||
public Response Execute(ActiveSync.RequestBase request)
|
public Response Execute(ActiveSync.RequestBase request)
|
||||||
{
|
{
|
||||||
string url = string.Format(ACTIVESYNC_URL, _account.ServerURL, _account.DeviceId,
|
string url = string.Format(ACTIVESYNC_URL, _account.Account.ServerURL, _account.Account.DeviceId,
|
||||||
request.Command, _account.UserName, "WindowsOutlook");
|
request.Command, _account.Account.UserName, "WindowsOutlook");
|
||||||
|
|
||||||
// Construct the body
|
// Construct the body
|
||||||
WBXMLDocument doc = new WBXMLDocument();
|
WBXMLDocument doc = new WBXMLDocument();
|
||||||
@ -291,10 +291,10 @@ namespace Acacia.ZPush.Connect
|
|||||||
|
|
||||||
using (HttpContent content = new ByteArrayContent(contentBody))
|
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");
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-sync.wbxml");
|
||||||
string caps = ZPushCapabilities.Client.ToString();
|
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);
|
content.Headers.Add(Constants.ZPUSH_HEADER_CLIENT_CAPABILITIES, caps);
|
||||||
using (HttpResponseMessage response = _client.PostAsync(url, content, _cancel).Result)
|
using (HttpResponseMessage response = _client.PostAsync(url, content, _cancel).Result)
|
||||||
{
|
{
|
||||||
|
@ -46,14 +46,14 @@ namespace Acacia.ZPush.Connect
|
|||||||
public ResponseType Execute<ResponseType>(SoapRequest<ResponseType> request)
|
public ResponseType Execute<ResponseType>(SoapRequest<ResponseType> request)
|
||||||
{
|
{
|
||||||
// Create the url
|
// 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,
|
ServiceName,
|
||||||
// TODO: this username is a bit of a quick hack.
|
// TODO: this username is a bit of a quick hack.
|
||||||
request.UserName ?? _connection.Account.UserName,
|
request.UserName ?? _connection.Account.Account.UserName,
|
||||||
"webservice");
|
"webservice");
|
||||||
|
|
||||||
// Set up the encoding
|
// 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;
|
encoder.ServiceName = ServiceName;
|
||||||
|
|
||||||
// Execute the request
|
// Execute the request
|
||||||
@ -85,7 +85,7 @@ namespace Acacia.ZPush.Connect
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
SoapParameters parameters = new SoapParameters();
|
SoapParameters parameters = new SoapParameters();
|
||||||
parameters.Add("devid", _connection.Account.DeviceId.ToLower());
|
parameters.Add("devid", _connection.Account.Account.DeviceId.ToLower());
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,143 +32,41 @@ using System.Threading.Tasks;
|
|||||||
namespace Acacia.ZPush
|
namespace Acacia.ZPush
|
||||||
{
|
{
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||||
public class ZPushAccount : DisposableWrapper, LogContext
|
public class ZPushAccount : LogContext
|
||||||
{
|
{
|
||||||
#region Miscellaneous
|
#region Miscellaneous
|
||||||
|
|
||||||
private readonly string _regPath;
|
private readonly IAccount _account;
|
||||||
|
|
||||||
private readonly IStore _store;
|
internal ZPushAccount(IAccount account)
|
||||||
|
|
||||||
/// <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)
|
|
||||||
{
|
{
|
||||||
this._regPath = regPath;
|
this._account = account;
|
||||||
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()
|
[Browsable(false)]
|
||||||
{
|
public IAccount Account { get { return _account; } }
|
||||||
_store.Dispose();
|
public String DisplayName { get { return _account.DisplayName; } }
|
||||||
}
|
|
||||||
|
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public string LogContextId
|
public string LogContextId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return "ZPushAccount(" + SmtpAddress + ")";
|
return "ZPushAccount(" + _account.SmtpAddress + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return SmtpAddress;
|
return _account.SmtpAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggers an Outlook send/receive operation.
|
/// Triggers an Outlook send/receive operation for this account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendReceive()
|
public void SendReceive()
|
||||||
{
|
{
|
||||||
// TODO: ThisAddIn.Instance.SendReceive();
|
ThisAddIn.Instance.SendReceive(Account);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -23,21 +23,19 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
|
||||||
|
|
||||||
namespace Acacia.ZPush
|
namespace Acacia.ZPush
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maintains the mapping from Outlook accounts to ZPush accounts, which
|
/// Maintains the mapping from Outlook accounts to ZPush accounts, which
|
||||||
/// provide additional functionality and workarounds.
|
/// provide additional functionality and workarounds.
|
||||||
|
/// TODO: split into Outlook and Z-Push specific parts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ZPushAccounts
|
public class ZPushAccounts : DisposableWrapper
|
||||||
{
|
{
|
||||||
private readonly ZPushWatcher _watcher;
|
private readonly ZPushWatcher _watcher;
|
||||||
// TODO: wrap these
|
private readonly IAddIn _addIn;
|
||||||
private readonly NSOutlook.Application _app;
|
private readonly IStores _stores;
|
||||||
private readonly NSOutlook.NameSpace _session;
|
|
||||||
private readonly NSOutlook.Stores _stores;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ZPushAccounts indexed by SMTPAddress. Null values are not allowed.
|
/// 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>();
|
private readonly Dictionary<string, ZPushAccount> _accountsBySmtp = new Dictionary<string, ZPushAccount>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ZPushAccounts indexed by store id. Null values are allowed, if a store has been
|
/// ZPushAccounts indexed by store id. Null values are noy allowed.
|
||||||
/// determined to not be associated with a ZPushAccount. This is required to determine when a store is new.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<string, ZPushAccount> _accountsByStoreId = new Dictionary<string, ZPushAccount>();
|
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._watcher = watcher;
|
||||||
this._app = app;
|
this._addIn = addIn;
|
||||||
this._session = app.Session;
|
this._stores = addIn.Stores;
|
||||||
this._stores = _session.Stores;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Start()
|
protected override void DoRelease()
|
||||||
{
|
{
|
||||||
// Register for new stores
|
_stores.Dispose();
|
||||||
// The store remove event is not sent, so don't register for that
|
}
|
||||||
_stores.StoreAdd += StoreAdded;
|
|
||||||
|
|
||||||
|
#region Implementation
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
if (GlobalOptions.INSTANCE.ZPushCheck)
|
if (GlobalOptions.INSTANCE.ZPushCheck)
|
||||||
{
|
{
|
||||||
// Process existing accounts
|
// Process existing accounts
|
||||||
using (ComRelease com = new ComRelease())
|
foreach (IAccount account in _stores.Accounts)
|
||||||
foreach (NSOutlook.Account account in com.Add(_session.Accounts))
|
|
||||||
{
|
{
|
||||||
Tasks.Task(null, "AccountCheck", () =>
|
Tasks.Task(null, "AccountCheck", () =>
|
||||||
{
|
{
|
||||||
try
|
AccountAdded(account);
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Tasks.Task(null, "AccountCheckDone", () =>
|
Tasks.Task(null, "AccountCheckDone", () =>
|
||||||
{
|
{
|
||||||
_watcher.OnAccountsScanned();
|
_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
|
try
|
||||||
{
|
{
|
||||||
// Collect all the store ids
|
Logger.Instance.Trace(this, "Checking account: {0}", account);
|
||||||
HashSet<string> stores = new HashSet<string>();
|
|
||||||
foreach (NSOutlook.Store store in _stores)
|
// Only EAS accounts can be zpush accounts
|
||||||
|
if (account.AccountType == AccountType.EAS)
|
||||||
{
|
{
|
||||||
try
|
ZPushAccount zpush = new ZPushAccount(account);
|
||||||
{
|
_accountsByStoreId.Add(account.StoreID, zpush);
|
||||||
stores.Add(store.StoreID);
|
_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
|
private void AccountRemoved(IAccount account)
|
||||||
List<KeyValuePair<string, ZPushAccount>> removed = new List<KeyValuePair<string, ZPushAccount>>();
|
|
||||||
foreach(KeyValuePair<string, ZPushAccount> account in _accountsByStoreId)
|
|
||||||
{
|
{
|
||||||
if (!stores.Contains(account.Key))
|
_accountsBySmtp.Remove(account.SmtpAddress);
|
||||||
{
|
_accountsByStoreId.Remove(account.StoreID);
|
||||||
Logger.Instance.Trace(this, "Store not found: {0} - {1}", account.Value, account.Key);
|
|
||||||
removed.Add(account);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any removed stores
|
#endregion
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<ZPushAccount> GetAccounts()
|
#region Account access
|
||||||
{
|
|
||||||
return _accountsBySmtp.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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)
|
public ZPushAccount GetAccount(IFolder folder)
|
||||||
{
|
{
|
||||||
ZPushAccount zpush = null;
|
ZPushAccount value = null;
|
||||||
using (IStore store = folder.Store)
|
_accountsByStoreId.TryGetValue(folder.StoreID, out value);
|
||||||
_accountsByStoreId.TryGetValue(store.StoreID, out zpush);
|
return value;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZPushAccount GetAccount(NSOutlook.MAPIFolder folder)
|
public ZPushAccount GetAccount(IAccount account)
|
||||||
{
|
{
|
||||||
using (ComRelease com = new ComRelease())
|
ZPushAccount value = null;
|
||||||
{
|
_accountsByStoreId.TryGetValue(account.StoreID, out value);
|
||||||
ZPushAccount zpush = null;
|
return value;
|
||||||
NSOutlook.Store store = com.Add(folder.Store);
|
|
||||||
string storeId = store?.StoreID;
|
|
||||||
if (storeId == null)
|
|
||||||
return null;
|
|
||||||
_accountsByStoreId.TryGetValue(storeId, out zpush);
|
|
||||||
return zpush;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
public ZPushAccount GetAccount(string smtpAddress)
|
||||||
{
|
{
|
||||||
ZPushAccount account = null;
|
ZPushAccount value = null;
|
||||||
_accountsBySmtp.TryGetValue(smtpAddress, out account);
|
_accountsBySmtp.TryGetValue(smtpAddress, out value);
|
||||||
return account;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public IEnumerable<ZPushAccount> GetAccounts()
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
try
|
return _accountsByStoreId.Values;
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -23,7 +23,6 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
|
||||||
|
|
||||||
namespace Acacia.ZPush
|
namespace Acacia.ZPush
|
||||||
{
|
{
|
||||||
@ -88,7 +87,7 @@ namespace Acacia.ZPush
|
|||||||
|
|
||||||
// Path found, create the store
|
// Path found, create the store
|
||||||
Logger.Instance.Info(typeof(ZPushLocalStore), "Creating new store: {0}", path);
|
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);
|
Logger.Instance.Debug(typeof(ZPushLocalStore), "Created new store: {0}", store.FilePath);
|
||||||
|
|
||||||
// Set the display name
|
// Set the display name
|
||||||
|
@ -53,7 +53,7 @@ namespace Acacia.ZPush
|
|||||||
this._addIn = addIn;
|
this._addIn = addIn;
|
||||||
this._app = addIn.RawApp;
|
this._app = addIn.RawApp;
|
||||||
Sync = new ZPushSync(this, addIn);
|
Sync = new ZPushSync(this, addIn);
|
||||||
Accounts = new ZPushAccounts(this, _app);
|
Accounts = new ZPushAccounts(this, addIn);
|
||||||
|
|
||||||
// Need to keep a link to keep receiving events
|
// Need to keep a link to keep receiving events
|
||||||
_explorer2 = _app.ActiveExplorer();
|
_explorer2 = _app.ActiveExplorer();
|
||||||
@ -77,43 +77,6 @@ namespace Acacia.ZPush
|
|||||||
|
|
||||||
#endregion
|
#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
|
#region Accounts
|
||||||
|
|
||||||
public delegate void AccountHandler(ZPushAccount account);
|
public delegate void AccountHandler(ZPushAccount account);
|
||||||
@ -134,18 +97,15 @@ namespace Acacia.ZPush
|
|||||||
/// Handles a new account.
|
/// Handles a new account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="account">The account.</param>
|
/// <param name="account">The account.</param>
|
||||||
/// <param name="isExisting">True if the account is an existing account, false if
|
internal void OnAccountDiscovered(ZPushAccount account)
|
||||||
/// it is a new account</param>
|
|
||||||
internal void OnAccountDiscovered(ZPushAccount account, bool isExisting)
|
|
||||||
{
|
{
|
||||||
// Notify any account listeners
|
// Notify any account listeners
|
||||||
if (AccountDiscovered != null)
|
AccountDiscovered?.Invoke(account);
|
||||||
AccountDiscovered(account);
|
|
||||||
|
|
||||||
// Register any events
|
// Register any events
|
||||||
HandleFolderWatchers(account);
|
HandleFolderWatchers(account);
|
||||||
|
|
||||||
if (account.HasPassword)
|
if (account.Account.HasPassword)
|
||||||
{
|
{
|
||||||
// Send an OOF request to get the OOF state and capabilities
|
// Send an OOF request to get the OOF state and capabilities
|
||||||
Tasks.Task(null, "ZPushCheck: " + account.DisplayName, () =>
|
Tasks.Task(null, "ZPushCheck: " + account.DisplayName, () =>
|
||||||
@ -274,7 +234,7 @@ namespace Acacia.ZPush
|
|||||||
private void HandleFolderWatchers(ZPushAccount account)
|
private void HandleFolderWatchers(ZPushAccount account)
|
||||||
{
|
{
|
||||||
// We need to keep the object alive to keep receiving events
|
// 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)
|
public void WatchFolder(FolderRegistration folder, FolderEventHandler handler, FolderEventHandler changedHandler = null)
|
||||||
@ -367,7 +327,7 @@ namespace Acacia.ZPush
|
|||||||
|
|
||||||
string entryId = folder.EntryID;
|
string entryId = folder.EntryID;
|
||||||
|
|
||||||
using (IStore store = folder.Store)
|
using (IStore store = folder.GetStore())
|
||||||
{
|
{
|
||||||
foreach(DefaultFolder defaultFolderId in BLACKLISTED_MAIL_FOLDERS)
|
foreach(DefaultFolder defaultFolderId in BLACKLISTED_MAIL_FOLDERS)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user