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

+111 -38
View File
@@ -48,12 +48,67 @@ VSTO/Outlook Interop API, но **первая сборка обязательн
Кнопка ленты **"Массовая рассылка"** появляется на вкладке "Главная"
основного окна Outlook (список писем), в группе "ssh-access-tui".
## Установка вне Visual Studio (ручной sideload)
## Установка вне Visual Studio
Это внутренний инструмент, поэтому здесь используется **sideload через
реестр**, а не полноценная публикация ClickOnce с веб-сервером или
раскатка через GPO (это отдельная задача на будущее, если понадобится
массово ставить плагин большому числу операторов).
Есть два способа поставить собранный плагин оператору. Оба используют один
и тот же build-output и один и тот же самоподписанный тестовый сертификат
(см. пункт про подпись ниже) — разница только в том, как Outlook узнаёт о
плагине.
### Способ А (рекомендуемый): локальная ClickOnce-публикация
Это тот же механизм установки/удаления, что использует практически любой
"нормальный" VSTO/Office-плагин (например, GpgOL для его COM-части) —
пользователь видит стандартный диалог "Установить это приложение?" при
установке и получает штатную запись в **Параметры → Приложения** для
удаления, без ручного редактирования реестра.
1. Из корня `outlook-bulk-sender\` запустите:
```
powershell -File deploy\publish-clickonce.ps1
```
Скрипт сам находит `MSBuild.exe` (сначала через `vswhere.exe`, с
фолбэком на `D:\VS2022\MSBuild\Current\Bin\amd64\MSBuild.exe`, если
vswhere не установлен или ничего не нашёл — путь можно переопределить
параметром `-MSBuildPath`) и запускает эквивалент:
```
MSBuild.exe BulkArchiveMailer.AddIn\BulkArchiveMailer.AddIn.csproj -t:Publish -p:Configuration=Release ^
-p:PublishUrl=C:\путь\к\проекту\BulkArchiveMailer.AddIn\bin\Release\app.publish\ ^
-p:InstallUrl=C:\путь\к\проекту\BulkArchiveMailer.AddIn\bin\Release\app.publish\ ^
-p:PublishDir=bin\Release\app.publish\ -p:UpdateEnabled=false
```
Тот же результат получится и вручную в Visual Studio: правой кнопкой на
`BulkArchiveMailer.AddIn` → **Publish...** → Publish location =
локальная папка (например, `bin\Release\app.publish\`) → Publish —
скрипт просто избавляет от необходимости помнить эти параметры и
набирать длинную команду руками при каждой пересборке инсталлятора.
2. Получится папка `app.publish\` с подпапкой `Application Files\` и
файлом `BulkArchiveMailer.AddIn.vsto` на верхнем уровне. Скопируйте
**всю папку `app.publish\` целиком** (структура важна — `.vsto`
ссылается на файлы в `Application Files\` относительным путём) на
рабочий компьютер оператора — сама папка при этом временная: ClickOnce
копирует файлы в свой собственный per-user кэш при установке, так что
исходную папку после установки можно удалить.
3. На рабочем компьютере — двойной клик по `BulkArchiveMailer.AddIn.vsto`.
Появится стандартный диалог установки Office-приложения (Publisher
будет "неизвестный", т.к. сертификат тестовый — см. ниже); подтвердить
установку.
4. **Удаление**: Параметры Windows → Приложения → Installed apps → найти
`BulkArchiveMailer.AddIn` → Uninstall. Ничего руками в реестре трогать
не нужно.
### Способ Б: ручной sideload через реестр
Более "hacky", но проще для сценариев без интерактивной установки
(автоматизированная раскатка через скрипт/GPO без диалогов). Плагин при
этом запускается прямо из указанной папки на диске, а не из ClickOnce-кэша
— удаление тоже полностью ручное (что и было единственным способом до
того, как способ А выше был проверен на реальной машине).
1. Соберите решение в конфигурации Release (Build → Configuration Manager
→ Release, затем Build Solution).
@@ -63,39 +118,61 @@ VSTO/Outlook Interop API, но **первая сборка обязательн
MSBuild-таргетами VSTO — в исходниках его нет и не должно быть,
`.gitignore` его игнорирует).
3. Скопируйте всю папку `bin\Release\` в постоянное место на диске
оператора (например, `C:\Tools\BulkArchiveMailer\`) — VSTO plug-in
должен запускаться из стабильного пути, а не из папки сборки, которая
может быть пересобрана/удалена.
4. Добавьте ключ реестра, которым Outlook находит плагин:
```
[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
```
(можно сохранить как `.reg`-файл и применить двойным щелчком).
5. Запустите Outlook. Поскольку манифест не подписан сертификатом
(`SignManifests=false` в `.csproj` — см. комментарий там же о причине),
при первой загрузке Outlook, скорее всего, покажет предупреждение
"не удалось проверить издателя" или подобное. Варианты:
оператора (например, `C:\Tools\BulkArchiveMailer\`) — в отличие от
способа А, здесь плагин должен запускаться из стабильного пути, а не
из папки сборки, которая может быть пересобрана/удалена.
4. Готовые `.reg`-файлы лежат в `outlook-bulk-sender\deploy\`:
`install-addin.reg` добавляет ключ
`HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\BulkArchiveMailer.AddIn`
(поправьте путь в `Manifest=`, если папка не `C:\Tools\BulkArchiveMailer\`),
`uninstall-addin.reg` — полностью его удаляет.
5. Запустите Outlook. VSTO не позволяет собрать Application-проект вообще
без подписи ClickOnce-манифеста (`VerifyClickOnceSigningSettings`
в `Microsoft.VisualStudio.Tools.Office.targets` останавливает сборку с
ошибкой, если `SignManifests=false`) — это обнаружилось только при
первой реальной сборке в Visual Studio, а не то решение, которое можно
было предугадать заранее. Поэтому в `BulkArchiveMailer.AddIn\` лежит
`BulkArchiveMailer.AddIn_TemporaryKey.pfx` — одноразовый самоподписанный
сертификат без пароля (`SignManifests=true`,
`ManifestCertificateThumbprint` в `.csproj`), сгенерированный ровно так
же, как это делает сама Visual Studio по кнопке "Create Test
Certificate..." на вкладке Signing. Он нужен только чтобы
удовлетворить это требование сборки и **не** делает плагин доверенным:
сертификат не от доверенного центра сертификации, поэтому Outlook
при первой загрузке всё равно, скорее всего, покажет предупреждение
"не удалось проверить издателя" или подобное. Варианты те же:
- принять предупреждение вручную (для одного оператора это разумно);
- добавить папку с плагином в доверенные расположения для VSTO:
`HKEY_CURRENT_USER\Software\Microsoft\VSTO\Security\Trust Manager\TrustedFolders\<любой уникальный ключ>` = путь к папке с `.vsto`, `String` REG_SZ.
- для более широкой раскатки — подписать манифест сертификатом
(Project Properties → Signing в Visual Studio) и настроить
доверие централизованно (GPO/сертификат в доверенных издателях) —
это уже упомянутое будущее развитие, не сделано в этой версии.
- для более широкой раскатки — подписать манифест сертификатом от
реального доверенного ЦС (Project Properties → Signing в Visual
Studio) и настроить доверие централизованно (GPO/сертификат в
доверенных издателях) — это уже упомянутое будущее развитие, не
сделано в этой версии.
## Типичные проблемы при первом открытии
Поскольку `.csproj`/`.sln` в этом решении написаны вручную (без мастера
Visual Studio, из-за отсутствия здесь Windows/VS/.NET SDK для
генерации), возможны мелкие расхождения с тем, что сгенерировал бы
реальный мастер "Outlook VSTO Add-in". Если сборка `BulkArchiveMailer.AddIn`
падает на ссылках `Microsoft.Office.*`/`Microsoft.VisualStudio.Tools.*`:
`BulkArchiveMailer.AddIn` был впервые собран вживую (Visual Studio 2022,
workload "Office/SharePoint development", `MSBuild.exe` — см. команду
сборки выше) после того, как `.csproj`/`.sln` какое-то время были написаны
вручную без доступа к Windows/VS. Первая реальная сборка нашла и потребовала
исправить два расхождения с настоящим VSTO API (уже исправлено в текущей
версии, здесь — для истории и на случай похожих проблем при доработке):
- `ThisAddIn`/`ThisAddIn.Designer.cs` наследовались от
`Microsoft.Office.Tools.Outlook.OutlookAddIn` — на практике это
интерфейс (только члены FormRegion), а не базовый класс. Реальный
конкретный базовый класс — `Microsoft.Office.Tools.Outlook.OutlookAddInBase`
из отдельной сборки `Microsoft.Office.Tools.Outlook.v4.0.Utilities.dll`
(ссылка `Private=True`, как в стандартном шаблоне "Outlook VSTO
Add-in" — см. `.csproj`).
- VSTO Application-проект не собирается вообще без подписи ClickOnce
манифеста (`SignManifests=false` раньше валил сборку с ошибкой
`VerifyClickOnceSigningSettings`) — отсюда одноразовый тестовый
сертификат `BulkArchiveMailer.AddIn_TemporaryKey.pfx`, см. пункт 5 выше.
Если сборка всё же падает на ссылках `Microsoft.Office.*`/
`Microsoft.VisualStudio.Tools.*` на другой машине:
1. Проверьте, что workload "Office/SharePoint development" точно
установлен (Visual Studio Installer → Modify).
@@ -112,10 +189,6 @@ Visual Studio, из-за отсутствия здесь Windows/VS/.NET SDK д
удалите атрибут версии в Solution Explorer и добавьте заново через
Add Reference — Visual Studio подставит то, что реально стоит на
машине.
4. TargetFrameworkVersion `v4.8` требует установленного .NET Framework 4.8
Developer Pack — Visual Studio предложит установить его сама при
4. TargetFrameworkVersion `v4.8.1` требует установленного .NET Framework
4.8.1 Developer Pack — Visual Studio предложит установить его сама при
открытии, если его нет.
Ничего из перечисленного не проверялось вживую — список составлен по
опыту работы с VSTO-проектами в целом, а не по факту увиденной ошибки в
этом конкретном решении.