在docker中编译vsto应用

限定windows容器

首先,正如这里所验证的,vsto的编译与调试需要使用Visual Studio的Office build tools

而且微软表示由于COM宿主(在这里是Office)只能支持一个.NET版本(.NET Framework 4.8),所以为了兼容以前的插件,将不会更新vsto至支持.net 5+,建议大家使用跨平台的Javascript APIs。虽然大家纷纷表示Javascript APIs就是一陀屎,但也只能被迫接受这个现实:vsto不支持跨平台的.net core。

综上,虽然我们可以用wine来支持msbuild(比如msbuild-docker),但想要编译vsto应用,只能够在windows容器中。

极其不愿意的使用windows容器

微软有官文档指导如何在windows容器上安装编译工具

基于官方示例,我们有两个修改点:

注意:如果宿主是Windows Server 2022,那就改回mcr.microsoft.com/windows/servercore:ltsc2022。除此之外与2019别无二致。

完整的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# escape=`

# Use the latest Windows Server Core 2019 image.
FROM mcr.microsoft.com/windows/servercore:ltsc2019

# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]

RUN `
# Download the Build Tools bootstrapper.
curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe `
`
# Install Build Tools with the Microsoft.VisualStudio.Workload.OfficeBuildTools workload, excluding workloads and components with known issues.
&& (start /w vs_buildtools.exe --quiet --wait --norestart --nocache `
--installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
--add Microsoft.VisualStudio.Workload.OfficeBuildTools --includeRecommended `
--add Microsoft.VisualStudio.Component.TeamOffice.BuildTools `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
--remove Microsoft.VisualStudio.Component.Windows81SDK `
|| IF "%ERRORLEVEL%"=="3010" EXIT 0) `
`
# Cleanup
&& del /q vs_buildtools.exe

# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

编译docker镜像

1
docker build -t buildtools:latest -m 4GB --progress=plain .

使用vsto-add-in-example项目来验证

1
2
3
Invoke-WebRequest -Uri https://github.com/suyu0925/vsto-add-in-example/archive/refs/heads/main.zip -OutFile vsto-add-in-example.zip
Expand-Archive vsto-add-in-example.zip -DestinationPath .
Rename-Item -Path "vsto-add-in-example-main" -NewName "vsto-add-in-example"

使用msbuild还原

1
2
3
4
5
6
docker run -it -v ${pwd}/vsto-add-in-example:C:/app buildtools
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.4.3
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
PS C:\> cd app; msbuild -m .\ExcelAddIn.sln -t:restore

修改发布网址

1
PS C:\app> (Get-Content .\ExcelAddIn\ExcelAddIn.csproj).replace('http://your.domain.com', 'http://debug.yourdomain.com') | Set-Content .\ExcelAddIn\ExcelAddIn.csproj

也可以直接使用xml

1
2
3
4
5
$xmlFileName = "${pwd}\ExcelAddIn\ExcelAddIn.csproj"
[xml]$xml = Get-Content $xmlFileName
$installUrl = Select-Xml -Xml $xml //ns:InstallUrl -Namespace @{ ns='http://schemas.microsoft.com/developer/msbuild/2003' }
$installUrl.Node.'#text' = 'http://debug.yourdomain.com'
$xml.Save($xmlFileName)

使用msbuild发布

1
PS C:\app> msbuild -m -t:publish /p:PublishDir="${pwd}.\publish"

bump版本号

1
2
3
4
5
$xmlFileName = "${pwd}\ExcelAddIn\ExcelAddIn.csproj"
[xml]$xml = Get-Content $xmlFileName
$appVersion = Select-Xml -Xml $xml //ns:ApplicationVersion -Namespace @{ ns='http://schemas.microsoft.com/developer/msbuild/2003' }
$appVersion.Node.'#text' = '1.0.1.0'
$xml.Save($xmlFileName)

验证成功。