如何获取 visual studio 使用的 clickonce 构建脚本来发布我的应用程序
How can I get the clickonce build script used by visual studio to publish my application
我有一个相当大的多项目解决方案。我目前在 Visual Studio 中构建它,然后使用右键单击 => 发布选项发布。这很好用。
我现在处于需要至少自动化 clickonce 发布的位置,这超出了我在 Visual Studio 中所能做的。我已经成功创建了一个 publish.xml 文件,我可以使用它与 msbuild 和 mage 一起创建看起来像 clickonce 的东西。但是,我在 visual studio 界面中的配置非常复杂,我希望能够简单地将其复制到我的 publish.xml 文件中。
当 visual studio 从右键单击 => 发布过程发布时,是否有可能 visual studio 生成提供 MSBuild and/or Mage 使用的属性的文件?
基本上,我想要一个配置文件,我可以用它来执行类似 msbuild publish.xml(或类似的)的操作,并准确获得 visual studio 生成的发布结果。
我目前使用的是 VS2017。该应用程序是使用 c#
的 winforms
这是我的 publish.xml。它不应该是测试之外的任何东西
<Project>
<PropertyGroup>
<OutputPathBuild>C:\Users\d_000\Documents\Visual Studio 2017\Projects\CP\CP.UI.Winforms\bin\x86\Debug</OutputPathBuild>
<Version>1.0.0.0</Version>
<OutputPathDeployment>C:\Users\d_000\Documents\CP Deploy\test</OutputPathDeployment>
<Mage>C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\mage.EXE</Mage>
</PropertyGroup>
<Target Name="Deployment">
<Error Condition="'$(Version)'==''" Text="The Version property must be defined in order to build the Deployment task."/>
<ItemGroup>
<DeploySource Include="$(OutputPathBuild)\**"/>
</ItemGroup>
<Copy SourceFiles="@(DeploySource)" DestinationFolder="$(OutputPathDeployment)\v$(Version)\%(RecursiveDir)"/>
<Exec Command='"$(Mage)" -New Application -ToFile "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -Name MyApp -Version $(Version) -Processor X86 -FromDirectory "$(OutputPathDeployment)\v$(Version)" -IconFile Resources\CPIcon.ico'/>
<Exec Command='"$(Mage)" -New Deployment -ToFile "$(OutputPathDeployment)\MyApp.application" -Name MyApp -Version $(Version) -Processor X86 -AppManifest "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -IncludeProviderURL true -ProviderURL "http://example.com/download/MyApp/MyApp.application" -Install true'/>
<!-- Grr... Mage tool has a bug whereby -MinVersion only works in Update mode... -->
<Exec Command='"$(Mage)" -Update "$(OutputPathDeployment)\MyApp.application" -MinVersion $(Version)'/>
<Copy SourceFiles="$(OutputPathDeployment)\MyApp.application" DestinationFiles="$(OutputPathDeployment)\MyApp.v$(Version).application"/>
</Target>
</Project>
编辑:
我需要自定义发布过程中的内容,因此我想了解 Visual Studio 在做什么。本质上,我想在 visual studio 中获取命令 运行,复制它们并调整它们,这样我就可以使用不同的 delpoy URL 和更新 URL 自动执行多个不同的构建
如果要为不同阶段创建 ClickOnce,则必须在调用 MSBuild 之前操作 proj 文件。
1) 阅读您的 .proj 文件
$projFilePath = Get-ChildItem $sourceRootDirectory -Filter $ProjectFileName -Recurse
$XmlDocument = [xml] (Get-Content -Path $projFilePath.FullName -Encoding UTF8)
2) 您必须在项目文件中更新此属性:
$ClickOnceForStages.Split("Dev", "Test", "UAT", "Prod") | Foreach {
$XmlDocument.project.PropertyGroup[0].ApplicationRevision = $BuildRevision
$XmlDocument.project.PropertyGroup[0].ApplicationVersion = $BuildVersion
$XmlDocument.project.PropertyGroup[0].ProductName = "MyProductName.$_"
$XmlDocument.project.PropertyGroup[0].AssemblyName = "MyAssemblyName.$_"
$XmlDocument.project.PropertyGroup[0].PublishUrl = "MyClickOnceDropUncPath_$_"
}
您必须确保:
$BuildRevision and $BuildVersion
每个版本都有一个增加的版本。
3) 保存文档而不操作原始项目文件。
$currentProjFilePath = $projFilePath.FullName +"_" + $_ + ".proj"
$XmlDocument.Save($clickOnceProjFilePath)
4) 调用 MSBuild 创建 ClickOnce 安装程序。
"C:\Program Files (x86)\MSBuild.0\Bin\MSBuild.exe"
您的项目文件与 ClickOnce 配置和 MSBuild 参数的组合:
"/target:publish"
创建 ClickOnce 安装程序。
这是我用来创建 ClickOnce 安装程序的完整 MSBuild 语句:
"$clickOnceProjFilePath",
"/target:publish",
"/p:PublishDir=$outputDirectory",
"/p:Configuration=Release"
k7 的工作帮助我找到了我的解决方案 - 所以我将其标记为答案,但这详细说明了我最终是如何解决它的。
所以,原来运行发布的所有信息都包含在项目文件中,你可以几乎就运行这个通过 msbuild(为清楚起见添加了换行符)。对于那些刚接触 csProj 文件体系结构的人来说,它包含许多通常用于构建、发布和配置的项目属性,以及一组目标,这有点像您可以完成的不同工作 运行。你 运行 他们通过使用 msbuild 指定 /t: 选项。未指定的目标不会执行。
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj" /t:publish
问题在于;
- 如果在构建命令中引用项目而不是解决方案,那么还需要指定解决方案文件夹
- 除非您在发布前指定重建,否则您对项目配置所做的任何更新都不会反映在输出中 - 如果您在多个配置下发布,这是一个问题
- 指定部署位置
- 您可能还想指定平台和配置
在这种情况下,我的命令变成了
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\
此时我正在重建和发布我的项目,就像我在 visual studio 中所做的那样。
当我想自定义时,我只是将附加信息添加到命令行中以覆盖;
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\
/p:UpdateUrl=http://example.com/
/p:ExcludeDeploymentUrl=false
我想更进一步并减少一些命令,所以我修改了 myProj.csProj - 但我想将代码分开。我通过在项目文件中的发布信息之后直接添加一个导入来做到这一点(这是 属性 组,成员包括 PublishURL 和 UpdateEnabled)。这直接在相关标签之后
<Import Project="CustomBuild.targets" />
不同配置包含的 CustomBuild.targets 文件。
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishType>none</PublishType>
</PropertyGroup>
<Choose>
<When Condition="'$(PublishType)' == 'web'">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Web\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Web\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>http://www.example.com/myAppUpdate</UpdateUrl>
<ExcludeDeploymentUrl>false</ExcludeDeploymentUrl>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
</PropertyGroup>
</When>
<When Condition=" '$(PublishType)' == 'network' ">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Network\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Network\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>\DummyServer\Share\</UpdateUrl>
<ExcludeDeploymentUrl>true</ExcludeDeploymentUrl>
</PropertyGroup>
</When>
</Choose>
</Project>
这段代码为我提供了两个配置(网络和网络),我可以通过一个简单的开关(在我的例子中是 PublishType)从命令行使用它们;
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release /p:PublishType=web
我的代码没有指定构建的自动增量,因为它与我无关,但是通过对 msbuild 工具和目标进行一些研究或者使用上面 k7 中的信息,这相对容易做到。
我有一个相当大的多项目解决方案。我目前在 Visual Studio 中构建它,然后使用右键单击 => 发布选项发布。这很好用。
我现在处于需要至少自动化 clickonce 发布的位置,这超出了我在 Visual Studio 中所能做的。我已经成功创建了一个 publish.xml 文件,我可以使用它与 msbuild 和 mage 一起创建看起来像 clickonce 的东西。但是,我在 visual studio 界面中的配置非常复杂,我希望能够简单地将其复制到我的 publish.xml 文件中。
当 visual studio 从右键单击 => 发布过程发布时,是否有可能 visual studio 生成提供 MSBuild and/or Mage 使用的属性的文件?
基本上,我想要一个配置文件,我可以用它来执行类似 msbuild publish.xml(或类似的)的操作,并准确获得 visual studio 生成的发布结果。
我目前使用的是 VS2017。该应用程序是使用 c#
的 winforms这是我的 publish.xml。它不应该是测试之外的任何东西
<Project>
<PropertyGroup>
<OutputPathBuild>C:\Users\d_000\Documents\Visual Studio 2017\Projects\CP\CP.UI.Winforms\bin\x86\Debug</OutputPathBuild>
<Version>1.0.0.0</Version>
<OutputPathDeployment>C:\Users\d_000\Documents\CP Deploy\test</OutputPathDeployment>
<Mage>C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\mage.EXE</Mage>
</PropertyGroup>
<Target Name="Deployment">
<Error Condition="'$(Version)'==''" Text="The Version property must be defined in order to build the Deployment task."/>
<ItemGroup>
<DeploySource Include="$(OutputPathBuild)\**"/>
</ItemGroup>
<Copy SourceFiles="@(DeploySource)" DestinationFolder="$(OutputPathDeployment)\v$(Version)\%(RecursiveDir)"/>
<Exec Command='"$(Mage)" -New Application -ToFile "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -Name MyApp -Version $(Version) -Processor X86 -FromDirectory "$(OutputPathDeployment)\v$(Version)" -IconFile Resources\CPIcon.ico'/>
<Exec Command='"$(Mage)" -New Deployment -ToFile "$(OutputPathDeployment)\MyApp.application" -Name MyApp -Version $(Version) -Processor X86 -AppManifest "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -IncludeProviderURL true -ProviderURL "http://example.com/download/MyApp/MyApp.application" -Install true'/>
<!-- Grr... Mage tool has a bug whereby -MinVersion only works in Update mode... -->
<Exec Command='"$(Mage)" -Update "$(OutputPathDeployment)\MyApp.application" -MinVersion $(Version)'/>
<Copy SourceFiles="$(OutputPathDeployment)\MyApp.application" DestinationFiles="$(OutputPathDeployment)\MyApp.v$(Version).application"/>
</Target>
</Project>
编辑:
我需要自定义发布过程中的内容,因此我想了解 Visual Studio 在做什么。本质上,我想在 visual studio 中获取命令 运行,复制它们并调整它们,这样我就可以使用不同的 delpoy URL 和更新 URL 自动执行多个不同的构建
如果要为不同阶段创建 ClickOnce,则必须在调用 MSBuild 之前操作 proj 文件。
1) 阅读您的 .proj 文件
$projFilePath = Get-ChildItem $sourceRootDirectory -Filter $ProjectFileName -Recurse
$XmlDocument = [xml] (Get-Content -Path $projFilePath.FullName -Encoding UTF8)
2) 您必须在项目文件中更新此属性:
$ClickOnceForStages.Split("Dev", "Test", "UAT", "Prod") | Foreach {
$XmlDocument.project.PropertyGroup[0].ApplicationRevision = $BuildRevision
$XmlDocument.project.PropertyGroup[0].ApplicationVersion = $BuildVersion
$XmlDocument.project.PropertyGroup[0].ProductName = "MyProductName.$_"
$XmlDocument.project.PropertyGroup[0].AssemblyName = "MyAssemblyName.$_"
$XmlDocument.project.PropertyGroup[0].PublishUrl = "MyClickOnceDropUncPath_$_"
}
您必须确保:
$BuildRevision and $BuildVersion
每个版本都有一个增加的版本。
3) 保存文档而不操作原始项目文件。
$currentProjFilePath = $projFilePath.FullName +"_" + $_ + ".proj"
$XmlDocument.Save($clickOnceProjFilePath)
4) 调用 MSBuild 创建 ClickOnce 安装程序。
"C:\Program Files (x86)\MSBuild.0\Bin\MSBuild.exe"
您的项目文件与 ClickOnce 配置和 MSBuild 参数的组合:
"/target:publish"
创建 ClickOnce 安装程序。
这是我用来创建 ClickOnce 安装程序的完整 MSBuild 语句:
"$clickOnceProjFilePath",
"/target:publish",
"/p:PublishDir=$outputDirectory",
"/p:Configuration=Release"
k7 的工作帮助我找到了我的解决方案 - 所以我将其标记为答案,但这详细说明了我最终是如何解决它的。
所以,原来运行发布的所有信息都包含在项目文件中,你可以几乎就运行这个通过 msbuild(为清楚起见添加了换行符)。对于那些刚接触 csProj 文件体系结构的人来说,它包含许多通常用于构建、发布和配置的项目属性,以及一组目标,这有点像您可以完成的不同工作 运行。你 运行 他们通过使用 msbuild 指定 /t: 选项。未指定的目标不会执行。
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj" /t:publish
问题在于;
- 如果在构建命令中引用项目而不是解决方案,那么还需要指定解决方案文件夹
- 除非您在发布前指定重建,否则您对项目配置所做的任何更新都不会反映在输出中 - 如果您在多个配置下发布,这是一个问题
- 指定部署位置
- 您可能还想指定平台和配置
在这种情况下,我的命令变成了
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\
此时我正在重建和发布我的项目,就像我在 visual studio 中所做的那样。
当我想自定义时,我只是将附加信息添加到命令行中以覆盖;
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\
/p:UpdateUrl=http://example.com/
/p:ExcludeDeploymentUrl=false
我想更进一步并减少一些命令,所以我修改了 myProj.csProj - 但我想将代码分开。我通过在项目文件中的发布信息之后直接添加一个导入来做到这一点(这是 属性 组,成员包括 PublishURL 和 UpdateEnabled)。这直接在相关标签之后
<Import Project="CustomBuild.targets" />
不同配置包含的 CustomBuild.targets 文件。
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishType>none</PublishType>
</PropertyGroup>
<Choose>
<When Condition="'$(PublishType)' == 'web'">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Web\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Web\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>http://www.example.com/myAppUpdate</UpdateUrl>
<ExcludeDeploymentUrl>false</ExcludeDeploymentUrl>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
</PropertyGroup>
</When>
<When Condition=" '$(PublishType)' == 'network' ">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Network\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Network\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>\DummyServer\Share\</UpdateUrl>
<ExcludeDeploymentUrl>true</ExcludeDeploymentUrl>
</PropertyGroup>
</When>
</Choose>
</Project>
这段代码为我提供了两个配置(网络和网络),我可以通过一个简单的开关(在我的例子中是 PublishType)从命令行使用它们;
"C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release /p:PublishType=web
我的代码没有指定构建的自动增量,因为它与我无关,但是通过对 msbuild 工具和目标进行一些研究或者使用上面 k7 中的信息,这相对容易做到。