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>
195 lines
15 KiB
Markdown
195 lines
15 KiB
Markdown
# Сборка и подключение BulkArchiveMailer
|
||
|
||
Это решение написано и ни разу не собрано в среде без Windows/Visual
|
||
Studio/.NET SDK — весь код написан вручную по памяти о реальных
|
||
VSTO/Outlook Interop API, но **первая сборка обязательно должна пройти на
|
||
вашей машине**, прежде чем этому плагину можно будет доверять. Ниже —
|
||
пошаговая инструкция и список мест, где по опыту чаще всего что-то не
|
||
сходится при первом открытии вручную написанного `.csproj`.
|
||
|
||
## Требования
|
||
|
||
- Windows 10/11.
|
||
- Классический Outlook (Win32 или Microsoft 365 C2R) — **не** "новый
|
||
Outlook" (он не поддерживает VSTO).
|
||
- Visual Studio 2022 (Community — бесплатная) с установленным workload'ом
|
||
**".NET desktop development"** И **"Office/SharePoint development"**
|
||
(последний ставит шаблоны VSTO, VSTO Runtime и Office Developer Tools —
|
||
без него сборка `BulkArchiveMailer.AddIn` не найдёт
|
||
`Microsoft.Office.Tools.*` сборки).
|
||
- Установленный **VSTO Runtime** (обычно ставится вместе с
|
||
Office/SharePoint workload'ом; если Outlook жалуется на "not a valid
|
||
Office Add-in" при загрузке — скорее всего он не установлен отдельно,
|
||
доустановите "Microsoft Visual Studio 2010 Tools for Office Runtime" /
|
||
актуальную версию VSTO Runtime).
|
||
|
||
## Открытие и сборка
|
||
|
||
1. Откройте `BulkArchiveMailer.sln` в Visual Studio.
|
||
2. Дайте NuGet восстановить пакеты (`BulkArchiveMailer.Core.Tests` тянет
|
||
xUnit + `Microsoft.NET.Test.Sdk`; `BulkArchiveMailer.Core` и
|
||
`BulkArchiveMailer.AddIn` NuGet-пакетов не используют вовсе — это
|
||
осознанное решение, см. `AppSettings.cs`, чтобы не зависеть от
|
||
восстановления пакетов в непроверенной среде).
|
||
3. Соберите решение (Build → Build Solution). Скорее всего первая сборка
|
||
пройдёт чисто, но если нет — см. раздел "Типичные проблемы" ниже.
|
||
4. `BulkArchiveMailer.Core.Tests` можно запустить через Test Explorer —
|
||
там сейчас один smoke-тест (`FilenameParserTests`), подтверждающий, что
|
||
тестовый проект в принципе собирается и видит `Core`. Полное покрытие
|
||
тестами — отдельная задача (dotnet-tester), не часть этой сборки.
|
||
|
||
## Отладка (F5)
|
||
|
||
Проект `BulkArchiveMailer.AddIn` настроен как VSTO Outlook Add-in — при
|
||
нажатии F5 (с ним как стартовым проектом) Visual Studio должна сама
|
||
зарегистрировать временную запись в реестре и запустить Outlook с уже
|
||
загруженным плагином. Если Outlook уже был открыт — закройте его перед F5.
|
||
|
||
Кнопка ленты **"Массовая рассылка"** появляется на вкладке "Главная"
|
||
основного окна Outlook (список писем), в группе "ssh-access-tui".
|
||
|
||
## Установка вне Visual Studio
|
||
|
||
Есть два способа поставить собранный плагин оператору. Оба используют один
|
||
и тот же 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).
|
||
2. В `BulkArchiveMailer.AddIn\bin\Release\` после сборки появятся, среди
|
||
прочего, `BulkArchiveMailer.AddIn.dll` и
|
||
`BulkArchiveMailer.AddIn.vsto` (манифест генерируется автоматически
|
||
MSBuild-таргетами VSTO — в исходниках его нет и не должно быть,
|
||
`.gitignore` его игнорирует).
|
||
3. Скопируйте всю папку `bin\Release\` в постоянное место на диске
|
||
оператора (например, `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/сертификат в
|
||
доверенных издателях) — это уже упомянутое будущее развитие, не
|
||
сделано в этой версии.
|
||
|
||
## Типичные проблемы при первом открытии
|
||
|
||
`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).
|
||
2. Если конкретная ссылка подсвечена жёлтым в Solution Explorer — правой
|
||
кнопкой на неё → Properties → сверьте путь; как правило, достаточно
|
||
удалить и заново добавить через Add Reference → Assemblies →
|
||
Extensions, найдя те же имена (`Microsoft.Office.Tools.Outlook` и
|
||
т.д.) — они должны там появиться, если workload установлен.
|
||
3. Если `Microsoft.Office.Interop.Outlook`/`office` не резолвятся с
|
||
версией `15.0.0.0` — это нормально расходится в зависимости от того,
|
||
какая версия Office PIA установлена; смените `Version=` в ссылке (в
|
||
`.csproj`, ищите `Microsoft.Office.Interop.Outlook`/`office`) на
|
||
установленную (`14.0.0.0` для Office 2010 PIA и т.п.) либо просто
|
||
удалите атрибут версии в Solution Explorer и добавьте заново через
|
||
Add Reference — Visual Studio подставит то, что реально стоит на
|
||
машине.
|
||
4. TargetFrameworkVersion `v4.8.1` требует установленного .NET Framework
|
||
4.8.1 Developer Pack — Visual Studio предложит установить его сама при
|
||
открытии, если его нет.
|