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>
This commit is contained in:
1 parent
7f0e0fdb23
commit
264ed74095
20 files changed
+756
-67
No files matched your search
@@ -0,0 +1,77 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user