Files
redlineoandClaude Sonnet 5 264ed74095 Fix first real VSTO build, add sender account selection, polish deploy
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>
2026-07-24 09:51:52 +03:00

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;
}
}
}