name: dotnet-clickonce-config description: 为.NET应用程序配置具有自动更新、先决条件管理和发布设置的ClickOnce部署 allowed-tools: Read, Write, Edit, Bash, Glob, Grep tags: [dotnet, clickonce, deployment, auto-update, windows]
dotnet-clickonce-config
为.NET应用程序配置具有自动更新能力、先决条件管理和发布设置的ClickOnce部署。此技能设置完整的ClickOnce部署流水线。
能力
- 配置ClickOnce发布设置
- 设置自动更新检查
- 管理应用程序先决条件
- 配置文件关联
- 设置证书签名
- 生成发布配置文件
- 配置部署清单
- 设置Web或文件共享部署
输入模式
{
"type": "object",
"properties": {
"projectPath": {
"type": "string",
"description": ".NET项目路径"
},
"publishSettings": {
"type": "object",
"properties": {
"publishUrl": { "type": "string" },
"installUrl": { "type": "string" },
"updateMode": { "enum": ["foreground", "background"] },
"updateInterval": { "type": "number" },
"minimumVersion": { "type": "string" }
}
},
"prerequisites": {
"type": "array",
"items": { "type": "string" }
},
"fileAssociations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"extension": { "type": "string" },
"description": { "type": "string" }
}
}
},
"signing": {
"type": "object",
"properties": {
"certificatePath": { "type": "string" },
"timestampUrl": { "type": "string" }
}
}
},
"required": ["projectPath", "publishSettings"]
}
输出模式
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": { "type": "string" },
"type": { "enum": ["pubxml", "manifest", "settings"] }
}
}
},
"publishCommand": { "type": "string" }
},
"required": ["success"]
}
.csproj配置
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<!-- ClickOnce设置 -->
<PublishUrl>https://myserver.com/myapp/</PublishUrl>
<InstallUrl>https://myserver.com/myapp/</InstallUrl>
<UpdateUrl>https://myserver.com/myapp/</UpdateUrl>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.*</ApplicationVersion>
<IsWebBootstrapper>true</IsWebBootstrapper>
<PublisherName>My Company</PublisherName>
<ProductName>My Application</ProductName>
<MapFileExtensions>true</MapFileExtensions>
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>true</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
</PropertyGroup>
<!-- 先决条件 -->
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
<Visible>False</Visible>
<ProductName>.NET Framework 4.8</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
</Project>
发布配置文件(pubxml)
<!-- Properties/PublishProfiles/ClickOnce.pubxml -->
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<PublishProtocol>ClickOnce</PublishProtocol>
<PublishDir>bin\publish\</PublishDir>
<PublishUrl>https://myserver.com/myapp/</PublishUrl>
<InstallUrl>https://myserver.com/myapp/</InstallUrl>
<UpdateUrl>https://myserver.com/myapp/</UpdateUrl>
<ApplicationVersion>1.0.0.*</ApplicationVersion>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>net8.0-windows</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>false</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
<!-- 安装设置 -->
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<CreateDesktopShortcut>true</CreateDesktopShortcut>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPageFileName>publish.htm</WebPageFileName>
<!-- 更新设置 -->
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>true</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<!-- 安全设置 -->
<SignManifests>true</SignManifests>
<ManifestCertificateThumbprint>1234567890ABCDEF</ManifestCertificateThumbprint>
<ManifestTimestampRFC3161Url>http://timestamp.digicert.com</ManifestTimestampRFC3161Url>
<!-- 文件关联 -->
<TargetCulture>en-US</TargetCulture>
<ProductName>My Application</ProductName>
<PublisherName>My Company</PublisherName>
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
</PropertyGroup>
</Project>
程序化更新检查
using System.Deployment.Application;
public class UpdateManager
{
public async Task<bool> CheckForUpdatesAsync()
{
if (!ApplicationDeployment.IsNetworkDeployed)
{
return false;
}
var deployment = ApplicationDeployment.CurrentDeployment;
try
{
var info = deployment.CheckForDetailedUpdate();
if (info.UpdateAvailable)
{
if (info.IsUpdateRequired)
{
// 强制更新
deployment.Update();
Application.Restart();
return true;
}
else
{
// 可选更新 - 提示用户
var result = MessageBox.Show(
$"版本 {info.AvailableVersion} 已可用。立即更新?",
"更新可用",
MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
deployment.Update();
Application.Restart();
return true;
}
}
}
}
catch (DeploymentDownloadException ex)
{
MessageBox.Show($"更新失败:{ex.Message}");
}
return false;
}
public Version GetCurrentVersion()
{
if (ApplicationDeployment.IsNetworkDeployed)
{
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
}
return Assembly.GetExecutingAssembly().GetName().Version;
}
}
发布命令
# 通过dotnet CLI发布
dotnet publish -p:PublishProfile=ClickOnce
# 通过MSBuild发布
msbuild /t:Publish /p:PublishProfile=ClickOnce
# 带版本增量发布
dotnet publish -p:PublishProfile=ClickOnce -p:ApplicationRevision=$(($(date +%s)))
签名配置
<!-- 使用证书签名清单 -->
<PropertyGroup>
<SignManifests>true</SignManifests>
<ManifestCertificateThumbprint>YOUR_CERT_THUMBPRINT</ManifestCertificateThumbprint>
<ManifestTimestampRFC3161Url>http://timestamp.digicert.com</ManifestTimestampRFC3161Url>
</PropertyGroup>
# 查找证书指纹
Get-ChildItem -Path Cert:\CurrentUser\My | Format-Table Thumbprint, Subject
# 手动签名
mage -sign MyApp.application -CertFile cert.pfx -Password mypassword
服务器设置(IIS)
<!-- 用于ClickOnce托管的web.config -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".application" mimeType="application/x-ms-application"/>
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest"/>
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream"/>
</staticContent>
</system.webServer>
</configuration>
最佳实践
- 始终签名清单:生产环境必需
- 使用语义版本控制:清晰的版本更新
- 设置最低版本:强制关键修复更新
- 测试更新流程:发布前验证
- 使用HTTPS:安全下载通道
- 监控发布文件夹:验证部署成功
相关技能
windows-authenticode-signer- 代码签名auto-update-system流程 - 更新工作流desktop-build-pipeline流程 - CI/CD
相关代理
wpf-dotnet-expert- .NET专业知识release-manager- 发布协调