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:
redlineoandClaude Sonnet 5 committed 2026-07-24 09:51:52 +03:00
1 parent 7f0e0fdb23
commit 264ed74095
20 files changed
+756 -67

No files matched your search

@@ -0,0 +1,12 @@
Windows Registry Editor Version 5.00
; Sideload регистрация BulkArchiveMailer для текущего пользователя.
; Перед применением скопируйте всю папку bin\Release\ в C:\Tools\BulkArchiveMailer\
; (или другой стабильный путь - тогда поправьте "Manifest" ниже под свой путь).
; Подробности и типичные проблемы - outlook-bulk-sender/docs/BUILD.md.
[HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\BulkArchiveMailer.AddIn]
"Description"="Массовая рассылка архивов ssh-access-tui"
"FriendlyName"="BulkArchiveMailer"
"Manifest"="file:///C:\\Tools\\BulkArchiveMailer\\BulkArchiveMailer.AddIn.vsto|vstolocal"
"LoadBehavior"=dword:00000003
@@ -0,0 +1,103 @@
<#
.SYNOPSIS
Rebuilds the ClickOnce installer for BulkArchiveMailer.AddIn (Способ А
in ../docs/BUILD.md) without hand-typing the long MSBuild -t:Publish
command each time.
.DESCRIPTION
Wraps:
MSBuild.exe BulkArchiveMailer.AddIn\BulkArchiveMailer.AddIn.csproj -t:Publish -p:Configuration=Release
-p:PublishUrl=<repo>\BulkArchiveMailer.AddIn\bin\Release\app.publish\
-p:InstallUrl=<repo>\BulkArchiveMailer.AddIn\bin\Release\app.publish\
-p:PublishDir=bin\Release\app.publish\ -p:UpdateEnabled=false
MSBuild.exe is located via vswhere.exe first (works across VS
installs/versions/editions); if vswhere itself isn't found, falls back
to the fixed path this repo has been built with so far
(D:\VS2022\MSBuild\Current\Bin\amd64\MSBuild.exe). Pass -MSBuildPath to
override either lookup explicitly.
.PARAMETER MSBuildPath
Explicit path to MSBuild.exe. Skips both the vswhere lookup and the
hardcoded fallback when supplied.
.EXAMPLE
.\deploy\publish-clickonce.ps1
.EXAMPLE
.\deploy\publish-clickonce.ps1 -MSBuildPath 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\MSBuild.exe'
#>
[CmdletBinding()]
param(
[string]$MSBuildPath
)
$ErrorActionPreference = 'Stop'
# Repo layout: this script lives in outlook-bulk-sender\deploy\, the
# project lives one level up in outlook-bulk-sender\BulkArchiveMailer.AddIn\.
$repoRoot = Split-Path -Parent $PSScriptRoot
$projectPath = Join-Path $repoRoot 'BulkArchiveMailer.AddIn\BulkArchiveMailer.AddIn.csproj'
$publishDir = Join-Path $repoRoot 'BulkArchiveMailer.AddIn\bin\Release\app.publish\'
if (-not (Test-Path $projectPath)) {
throw "Project file not found: $projectPath"
}
function Resolve-MSBuildPath {
param([string]$explicitPath)
if ($explicitPath) {
if (-not (Test-Path $explicitPath)) {
throw "-MSBuildPath was given but does not exist: $explicitPath"
}
return $explicitPath
}
$vswhere = 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe'
if (Test-Path $vswhere) {
$found = & $vswhere -latest -requires Microsoft.Component.MSBuild -find 'MSBuild\**\Bin\MSBuild.exe' 2>$null |
Select-Object -First 1
if ($found -and (Test-Path $found)) {
Write-Host "Using MSBuild found via vswhere: $found"
return $found
}
Write-Warning 'vswhere.exe ran but did not report a usable MSBuild.exe - falling back to the fixed path.'
} else {
Write-Warning "vswhere.exe not found at '$vswhere' - falling back to the fixed path."
}
$fallback = 'D:\VS2022\MSBuild\Current\Bin\amd64\MSBuild.exe'
if (-not (Test-Path $fallback)) {
throw "Could not locate MSBuild.exe via vswhere, and the fallback path does not exist either: $fallback. Pass -MSBuildPath explicitly."
}
Write-Host "Using fallback MSBuild path: $fallback"
return $fallback
}
$msbuild = Resolve-MSBuildPath -explicitPath $MSBuildPath
Write-Host "Publishing $projectPath (Release, local ClickOnce, updates disabled) to:`n $publishDir"
& $msbuild $projectPath `
-t:Publish `
-p:Configuration=Release `
-p:PublishUrl=$publishDir `
-p:InstallUrl=$publishDir `
-p:PublishDir=$publishDir `
-p:UpdateEnabled=false `
-m
if ($LASTEXITCODE -ne 0) {
throw "MSBuild -t:Publish failed with exit code $LASTEXITCODE"
}
$vstoPath = Join-Path $publishDir 'BulkArchiveMailer.AddIn.vsto'
if (Test-Path $vstoPath) {
Write-Host "`nDone. Installer manifest: $vstoPath"
Write-Host "Copy the whole 'app.publish' folder to the operator's machine and double-click the .vsto file there (see docs/BUILD.md, Способ А)."
} else {
Write-Warning "Publish reported success but $vstoPath was not found - check the MSBuild output above."
}
@@ -0,0 +1,8 @@
Windows Registry Editor Version 5.00
; Полностью убирает регистрацию BulkArchiveMailer из Outlook для текущего
; пользователя (обратное к install-addin.reg). Закройте Outlook перед
; применением. После применения можно вручную удалить папку с файлами
; плагина (например, C:\Tools\BulkArchiveMailer\), если она больше не нужна.
[-HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\BulkArchiveMailer.AddIn]