First live build against real Visual Studio/VSTO tooling surfaced two issues in the hand-written AddIn scaffold: ThisAddIn derived from the wrong base type (OutlookAddIn is an interface, not the concrete OutlookAddInBase class), and VSTO Application projects cannot build without a signed ClickOnce manifest, so SignManifests is now on with a throwaway self-signed test certificate. Both Core/Core.Tests/AddIn now build clean and Core.Tests passes. Also: mail always sent from Outlook's default account with no way to pick a different one (e.g. a shared mailbox) - added a "From account" setting (Session.Accounts dropdown in SettingsForm, SendUsingAccount in MailSender). And added deploy/ with both a local ClickOnce publish script (real install/uninstall via Windows Apps, no manual registry editing) and a manual registry sideload fallback for scripted rollouts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
78 lines
2.7 KiB
C#
78 lines
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using Outlook = Microsoft.Office.Interop.Outlook;
|
|
|
|
namespace BulkArchiveMailer.AddIn
|
|
{
|
|
/// <summary>Read-only snapshot of one Outlook.Account, taken once while the COM object was still alive - safe to hold onto and display after the Account RCW itself has been released.</summary>
|
|
public sealed class OutlookAccountInfo
|
|
{
|
|
public string DisplayName { get; set; } = "";
|
|
public string SmtpAddress { get; set; } = "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enumerates Outlook.Application.Session.Accounts for UI purposes
|
|
/// (the "Отправлять от:" picker in SettingsForm) without leaking any
|
|
/// COM references - mirrors the release-what-you-touch convention used
|
|
/// in MailSender/SignatureReader. Never throws: on any failure it
|
|
/// returns an empty list so a picker can simply fall back to "default
|
|
/// account only" instead of crashing the Settings window.
|
|
/// </summary>
|
|
public static class OutlookAccounts
|
|
{
|
|
public static List<OutlookAccountInfo> ListAccounts(Outlook.Application application)
|
|
{
|
|
var result = new List<OutlookAccountInfo>();
|
|
if (application == null)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
Outlook.Accounts accounts = null;
|
|
try
|
|
{
|
|
accounts = application.Session.Accounts;
|
|
foreach (Outlook.Account account in accounts)
|
|
{
|
|
try
|
|
{
|
|
result.Add(new OutlookAccountInfo
|
|
{
|
|
DisplayName = account.DisplayName ?? "",
|
|
SmtpAddress = account.SmtpAddress ?? "",
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
// Skip an individual account we couldn't read
|
|
// rather than losing the rest of the list.
|
|
}
|
|
finally
|
|
{
|
|
Marshal.ReleaseComObject(account);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return new List<OutlookAccountInfo>();
|
|
}
|
|
finally
|
|
{
|
|
if (accounts != null)
|
|
{
|
|
Marshal.ReleaseComObject(accounts);
|
|
}
|
|
|
|
// application.Session (NameSpace) is a long-lived object
|
|
// owned by Outlook itself - never released here, same as
|
|
// in MailSender.
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|