概述
一般情况下,Visual Studio提供了的发布功能能够满足基础的需求。
但在实际开发过程中,对于复杂的项目,多个项目组成的大型项目,或者需要CICD的项目,往往都是需要脚本来控制发布的各个步骤。
例如:
- 多个子项目的版本统一修改
- 按序生成发布
- 辅助文档生成编译
- 相关文件的拷贝复制
- 不同格式、平台的安装包。
虽然VS也能够通过生成前后的事件来控制,但还是没有单独的脚本方便管理。
下面,我将以自身项目的某个脚本来详细阐述。
脚本样例 Build.ps1
param (
[switch]$help,
[Parameter(Mandatory = $false)][bool]$publish_Free_Installer = $false,
[Parameter(Mandatory = $false)][bool]$publish_MSI_Installer = $false,
[Parameter(Mandatory = $false)][bool]$updateVersion = $false,
[Parameter(Mandatory = $false)][int]$major_ver,
[Parameter(Mandatory = $false)][int]$minor_ver,
[Parameter(Mandatory = $false)][int]$patch_ver
)
[string]$MsBuild = " "
[string]$Proj = "$PSScriptRoot\..\ToolsKit\DeviceToolsKit.csproj"
[string]$TempPackage_Path = "$PSScriptRoot\..\TempPackage"
[string]$Delivery_Path = "$PSScriptRoot\..\Delivery"
[string]$Installer_proj = "$PSScriptRoot\..\ProjectInstaller\ProjectInstaller.vdproj"
function ChangeVersionNumberInFile($file, $major, $minor, $patch)
{
Write-Host "Changing version in $file to $major.$minor.$patch"
$sr = new-object System.IO.StreamReader( $file, [System.Text.Encoding]::GetEncoding("utf-8") )
$content = $sr.ReadToEnd()
$sr.Close()
switch([System.IO.Path]::GetExtension($file))
{
".json" {$content = [Regex]::Replace($content, 'Hydra (\d+)\.(\d+).(\d+)',"Hydra $major.$minor.$patch"); Break}
".csproj" {$content = [Regex]::Replace($content, "<Version>(\d+).(\d+).(\d+)</Version>", "<Version>$major.$minor.$patch</Version>"); Break}
".cs" {$content = [Regex]::Replace($content, '"(\d+)\.(\d+).(\d+)','"' + "$major.$minor.$patch"); Break}
".appxmanifest" {$content = [Regex]::Replace($content, ' Version="(\d+)\.(\d+).(\d+)',' Version="' + "$major.$minor.$patch"); Break}
}
$sw = new-object System.IO.StreamWriter( $file, $false, [System.Text.Encoding]::GetEncoding("utf-8") )
$sw.Write( $content )
$sw.Close()
}
function uuid { [guid]::NewGuid().ToString().ToUpper() }
function SetInstallerVersion ($file, $version)
{
Write-Host "Changing version in $file to $version"
$sr = new-object System.IO.StreamReader( $file, [System.Text.Encoding]::GetEncoding("utf-8") )
$content = $sr.ReadToEnd()
$sr.Close()
$content = [Regex]::Replace($content, '"ProductVersion" = "8:"', '"ProductVersion" = "8:'+$version+'"');
$content = [Regex]::Replace($content, '"ProductVersion" = "8:(\d+)\.(\d+)"', '"ProductVersion" = "8:'+$version+'"');
$content = [Regex]::Replace($content, '"ProductVersion" = "8:(\d+)\.(\d+)\.(\d+)"', '"ProductVersion" = "8:'+$version+'"');
[string] $ProductCode = uuid
[string] $PackageCode = uuid
$content = [Regex]::Replace($content, '"ProductCode" = "8:{(\w{8})-(\w{4})-(\w{4})-(\w{4})-(\w{12})}"', '"ProductCode" = "8:{' + $ProductCode + '}"');
$content = [Regex]::Replace($content, '"PackageCode" = "8:{(\w{8})-(\w{4})-(\w{4})-(\w{4})-(\w{12})}"', '"PackageCode" = "8:{' + $PackageCode + '}"');
$sw = new-object System.IO.StreamWriter( $file, $false, [System.Text.Encoding]::GetEncoding("utf-8") )
$sw.Write( $content )
$sw.Close()
}
function UpdateVersion()
{
"--------------------------------------------"
"-- Update project version --"
"--------------------------------------------"
ChangeVersionNumberInFile $Proj $major_ver $minor_ver $patch_ver
"--------------------------------------------"
"-- Update installer version --"
"--------------------------------------------"
$targetVersion ="$major_ver.$minor_ver.$patch_ver"
SetInstallerVersion $Installer_proj $targetVersion
}
function FindMSBuildPath()
{
if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
}
elseif (Test-Path "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
}
else{
throw "Unable to find MSBuild.exe path"
}
return $msBuild
}
function RestoreNuget($proj)
{
"-----NuGet Restore: $proj-----"
& "$PSScriptRoot\..\Tools\nuget.exe" restore "$proj"
}
function PublishFreeInstallPackage()
{
"---------------------------------------------"
"-- Publish Free Install Package --"
"---------------------------------------------"
RestoreNuget($Proj)
dotnet clean $Proj -c Release
dotnet build $Proj -c Release --force
if ($LASTEXITCODE -ne 0) {
exit $lastexitcode
}
"-----Publish Project-----"
dotnet publish $Proj -c Release -p:PublishProfile=FolderProfile
}
function PublishMSIInstallPackage()
{
"---------------------------------------------"
"-- Publish MSI Install Package --"
"---------------------------------------------"
""
"-------------------------"
"-- Build current project --"
"-------------------------"
RestoreNuget($Proj)
dotnet clean $Proj -c Release
dotnet build $Proj -c Release --force
if($MsBuild -eq " ")
{
$MSBuild = FindMSBuildPath
}
& $MsBuild $Proj /p:Configuration=Release /t:Clean,Build
if ($LASTEXITCODE -ne 0) {
exit $lastexitcode
}
"-----------------------------"
"-- Build Installer project --"
"-----------------------------"
#[string]$Installer_proj = "$PSScriptRoot\..\ProjectInstaller\ProjectInstaller.vdproj"
#if($Sign -eq $True)
#{
#Add pre build event to sign .exe after rebuilding project but before building installer
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:call \"$(ProjectDir)/../../../build/certificates/certificate.bat\" \"$(ProjectDir)..\\..\\..\\out\\application_studio_$(Configuration)\\$(Configuration)\\application_studio.exe\"\r\n"'
# }
$devenvDir = FindDevenvdPath
Remove-Item -Path "$PSScriptRoot\..\out\Installer\Release\*" -Recurse -Force -ErrorAction SilentlyContinue
& $devenvDir "$PSScriptRoot\..\DeviceToolsKit.sln" /project $Installer_proj /Build Release
if ($LASTEXITCODE -ne 0) {
# Remove pre build event from installer proj file if failed to sign
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:"'
exit $lastexitcode
}
$fullName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name
$AppName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name.Split('.')[0]
$major_ver, $minor_ver, $patch_ver = GetVersionOfFile $Proj
$targetVersion ="$major_ver.$minor_ver.$patch_ver"
$installerName = $AppName + "_v" + $targetVersion + ".msi"
"Installer Name: $installerName"
Rename-Item -Path "$PSScriptRoot\..\ProjectInstaller\Release\$fullName" -NewName $installerName
# if($Sign -eq $True)
# {
# Sign Installer
#& "$PSScriptRoot\certificates\certificate.bat" "$PSScriptRoot\..\out\Installer\Release\*.msi"
# Remove pre build event from installer proj file after signing
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:"'
# }
}
function FindDevenvdPath()
{
if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com"
}
else {
Write-Error "devenv.com does not exista, make sure Microsoft Visual Studio Installer Projects is installed"
exit $lastexitcode
}
return $devenvDir
}
function CopyMSIPackagesToDelivery
{
"----- Copy MSI Packages To Delivery -----"
$verStr = GetVersionStr $Proj
$Delivery_FullPath=$Delivery_Path+"\DeviceToolsKit_v"+$verStr+"_InstallPackage"
"----- Target path -----"
Write-Output $Delivery_FullPath
$check4 = Test-Path $Delivery_Path
if ($check4.ToString().Equals("False")) {
mkdir $Delivery_Path
}
$check5 = Test-Path $Delivery_FullPath
if ($check5.ToString().Equals("False")) {
mkdir $Delivery_FullPath
}
#"$PSScriptRoot\..\ProjectInstaller\Release\$fullName"
xcopy $PSScriptRoot\..\ProjectInstaller\Release\*.* $Delivery_FullPath /E/H/C/I/y
}
function CopyFreeInstallPackagesToDelivery
{
"----- Copy Install Free Packages To Delivery -----"
$verStr = GetVersionStr $Proj
$Delivery_FullPath=$Delivery_Path+"\DeviceToolsKit_v"+$verStr+"_InstallFree"
"----- Target path -----"
Write-Output $Delivery_FullPath
$check4 = Test-Path $Delivery_Path
if ($check4.ToString().Equals("False")) {
mkdir $Delivery_Path
}
$check5 = Test-Path $Delivery_FullPath
if ($check5.ToString().Equals("False")) {
mkdir $Delivery_FullPath
}
xcopy $TempPackage_Path\*.* $Delivery_FullPath /E/H/C/I/y
}
function GetVersionStr($file)
{
$content = Get-Content $file
switch([System.IO.Path]::GetExtension($file))
{
".csproj" {$versionStr = ($content | Select-String "<Version>(\d+).(\d+).(\d+)</Version>") -replace "[^0-9 | .]",'' ; Break}
default {Write-Error "Unable to get version from $file"; exit}
}
return $versionStr
}
function GetVersionOfFile($file)
{
$content = Get-Content $file
switch([System.IO.Path]::GetExtension($file))
{
".csproj" {$version = ($content | Select-String "<Version>(\d+).(\d+).(\d+)</Version>") -replace "[^0-9 | .]",'' ; Break}
default {Write-Error "Unable to get version from $file"; exit}
}
Write-Host "Version $version in file: $file"
return $version.Split(".")
}
##########Start of build script##########
if($help)
{
Write-Host "
Arguments: null
"
exit
}
if($updateVersion)
{
if(!$PSBoundParameters.ContainsKey('major_ver') -and !$PSBoundParameters.ContainsKey('minor_ver') -and !$PSBoundParameters.ContainsKey('patch_ver'))
{
$major_ver, $minor_ver, $patch_ver = GetVersionOfFile $Proj
$patch_ver = $patch_ver + 1
}
elseif(!$PSBoundParameters.ContainsKey('major_ver') -xor !$PSBoundParameters.ContainsKey('minor_ver') -xor !$PSBoundParameters.ContainsKey('patch_ver'))
{
Write-Error "All Version Parameters must be set: Major, Minor, Patch"
exit
}
UpdateVersion
}
if($publish_Free_Installer)
{
$MSBuild = FindMSBuildPath
PublishFreeInstallPackage
CopyFreeInstallPackagesToDelivery
}
if($publish_MSI_Installer)
{
$MSBuild = FindMSBuildPath
PublishMSIInstallPackage
CopyMSIPackagesToDelivery
}
解释说明
1.参数部分
param (
[switch]$help,
[Parameter(Mandatory = $false)][bool]$publish_Free_Installer = $false,
[Parameter(Mandatory = $false)][bool]$publish_MSI_Installer = $false,
[Parameter(Mandatory = $false)][bool]$updateVersion = $false,
[Parameter(Mandatory = $false)][int]$major_ver,
[Parameter(Mandatory = $false)][int]$minor_ver,
[Parameter(Mandatory = $false)][int]$patch_ver
)
这个power shell 可以通过脚本来启动对应的功能。
不同的参数,可以达到不同的目的。
这里主要实现了三个功能:
- 版本修改(针对主项目,以及一个InstallerSetup项目)
- 发布免安装版本
- 发布MSI的安装包
2.脚本程序的入口
##########Start of build script##########
if($help)
{
Write-Host "
Arguments: null
"
exit
}
if($updateVersion)
{
if(!$PSBoundParameters.ContainsKey('major_ver') -and !$PSBoundParameters.ContainsKey('minor_ver') -and !$PSBoundParameters.ContainsKey('patch_ver'))
{
$major_ver, $minor_ver, $patch_ver = GetVersionOfFile $Proj
$patch_ver = $patch_ver + 1
}
elseif(!$PSBoundParameters.ContainsKey('major_ver') -xor !$PSBoundParameters.ContainsKey('minor_ver') -xor !$PSBoundParameters.ContainsKey('patch_ver'))
{
Write-Error "All Version Parameters must be set: Major, Minor, Patch"
exit
}
UpdateVersion
}
if($publish_Free_Installer)
{
$MSBuild = FindMSBuildPath
PublishFreeInstallPackage
CopyFreeInstallPackagesToDelivery
}
if($publish_MSI_Installer)
{
$MSBuild = FindMSBuildPath
PublishMSIInstallPackage
CopyMSIPackagesToDelivery
}
通过不同的输入参数,执行对应的方法。
主要包括了:
- 自动版本号增加 1
- 修改成指定的版本号
- 发布免安装版本,并将结果文件复制到Delivery文件夹
- 发布MSI安装包,并将结果文件复制到Delivery文件夹
3. 自定义的路径变量
[string]$MsBuild = " "
[string]$Proj = "$PSScriptRoot\..\ToolsKit\DeviceToolsKit.csproj"
[string]$TempPackage_Path = "$PSScriptRoot\..\TempPackage"
[string]$Delivery_Path = "$PSScriptRoot\..\Delivery"
[string]$Installer_proj = "$PSScriptRoot\..\ProjectInstaller\ProjectInstaller.vdproj"
通过上述代码,定义了项目的主要csproj文件的路径
以及最终发布文件的存放位置。
注意,这都是相对路径,需要根据自己项目需求进行修改。
4.修改项目的版本号
(a)修改主项目的版本号
- $file 是项目的csproj路径。
- 如果csproj中没有version字段,将会执行失败,需要先行添加版本信息,然后这个脚本就能正常执行。
function ChangeVersionNumberInFile($file, $major, $minor, $patch)
{
Write-Host "Changing version in $file to $major.$minor.$patch"
$sr = new-object System.IO.StreamReader( $file, [System.Text.Encoding]::GetEncoding("utf-8") )
$content = $sr.ReadToEnd()
$sr.Close()
switch([System.IO.Path]::GetExtension($file))
{
".json" {$content = [Regex]::Replace($content, 'Hydra (\d+)\.(\d+).(\d+)',"Hydra $major.$minor.$patch"); Break}
".csproj" {$content = [Regex]::Replace($content, "<Version>(\d+).(\d+).(\d+)</Version>", "<Version>$major.$minor.$patch</Version>"); Break}
".cs" {$content = [Regex]::Replace($content, '"(\d+)\.(\d+).(\d+)','"' + "$major.$minor.$patch"); Break}
".appxmanifest" {$content = [Regex]::Replace($content, ' Version="(\d+)\.(\d+).(\d+)',' Version="' + "$major.$minor.$patch"); Break}
}
$sw = new-object System.IO.StreamWriter( $file, $false, [System.Text.Encoding]::GetEncoding("utf-8") )
$sw.Write( $content )
$sw.Close()
}
(b)修改InstallerSetup的版本号
这个安装程序项目的版本号比较特殊。
修改版本号的同时,需要重新生成产品编号。
function uuid { [guid]::NewGuid().ToString().ToUpper() }
function SetInstallerVersion ($file, $version)
{
Write-Host "Changing version in $file to $version"
$sr = new-object System.IO.StreamReader( $file, [System.Text.Encoding]::GetEncoding("utf-8") )
$content = $sr.ReadToEnd()
$sr.Close()
$content = [Regex]::Replace($content, '"ProductVersion" = "8:"', '"ProductVersion" = "8:'+$version+'"');
$content = [Regex]::Replace($content, '"ProductVersion" = "8:(\d+)\.(\d+)"', '"ProductVersion" = "8:'+$version+'"');
$content = [Regex]::Replace($content, '"ProductVersion" = "8:(\d+)\.(\d+)\.(\d+)"', '"ProductVersion" = "8:'+$version+'"');
[string] $ProductCode = uuid
[string] $PackageCode = uuid
$content = [Regex]::Replace($content, '"ProductCode" = "8:{(\w{8})-(\w{4})-(\w{4})-(\w{4})-(\w{12})}"', '"ProductCode" = "8:{' + $ProductCode + '}"');
$content = [Regex]::Replace($content, '"PackageCode" = "8:{(\w{8})-(\w{4})-(\w{4})-(\w{4})-(\w{12})}"', '"PackageCode" = "8:{' + $PackageCode + '}"');
$sw = new-object System.IO.StreamWriter( $file, $false, [System.Text.Encoding]::GetEncoding("utf-8") )
$sw.Write( $content )
$sw.Close()
}
5.查找本地的MSBuild、devenv工具
这两个工具将被不同的发布方式调用。
function FindMSBuildPath()
{
if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
}
elseif (Test-Path "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe") {
$msBuild = "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
}
else{
throw "Unable to find MSBuild.exe path"
}
return $msBuild
}
function FindDevenvdPath()
{
if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com"
}
elseif (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com") {
$devenvDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com"
}
else {
Write-Error "devenv.com does not exista, make sure Microsoft Visual Studio Installer Projects is installed"
exit $lastexitcode
}
return $devenvDir
}
6.重置并还原Nuget包
需要在项目中,在…\Tools\路径下,添加一个工具nuget.exe,这样才能正常调用该方法。
function RestoreNuget($proj)
{
"-----NuGet Restore: $proj-----"
& "$PSScriptRoot\..\Tools\nuget.exe" restore "$proj"
}
7.发布免安装版本
function PublishFreeInstallPackage()
{
"---------------------------------------------"
"-- Publish Free Install Package --"
"---------------------------------------------"
RestoreNuget($Proj)
dotnet clean $Proj -c Release
dotnet build $Proj -c Release --force
if ($LASTEXITCODE -ne 0) {
exit $lastexitcode
}
"-----Publish Project-----"
dotnet publish $Proj -c Release -p:PublishProfile=FolderProfile
}
通过
-p:PublishProfile=FolderProfile
调用了实现在项目中制定的publish配置文件。
8.发布MSI的安装包
function PublishMSIInstallPackage()
{
"---------------------------------------------"
"-- Publish MSI Install Package --"
"---------------------------------------------"
""
"-------------------------"
"-- Build current project --"
"-------------------------"
RestoreNuget($Proj)
dotnet clean $Proj -c Release
dotnet build $Proj -c Release --force
if($MsBuild -eq " ")
{
$MSBuild = FindMSBuildPath
}
& $MsBuild $Proj /p:Configuration=Release /t:Clean,Build
if ($LASTEXITCODE -ne 0) {
exit $lastexitcode
}
"-----------------------------"
"-- Build Installer project --"
"-----------------------------"
#[string]$Installer_proj = "$PSScriptRoot\..\ProjectInstaller\ProjectInstaller.vdproj"
#if($Sign -eq $True)
#{
#Add pre build event to sign .exe after rebuilding project but before building installer
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:call \"$(ProjectDir)/../../../build/certificates/certificate.bat\" \"$(ProjectDir)..\\..\\..\\out\\application_studio_$(Configuration)\\$(Configuration)\\application_studio.exe\"\r\n"'
# }
$devenvDir = FindDevenvdPath
Remove-Item -Path "$PSScriptRoot\..\out\Installer\Release\*" -Recurse -Force -ErrorAction SilentlyContinue
& $devenvDir "$PSScriptRoot\..\DeviceToolsKit.sln" /project $Installer_proj /Build Release
if ($LASTEXITCODE -ne 0) {
# Remove pre build event from installer proj file if failed to sign
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:"'
exit $lastexitcode
}
$fullName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name
$AppName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name.Split('.')[0]
$major_ver, $minor_ver, $patch_ver = GetVersionOfFile $Proj
$targetVersion ="$major_ver.$minor_ver.$patch_ver"
$installerName = $AppName + "_v" + $targetVersion + ".msi"
"Installer Name: $installerName"
Rename-Item -Path "$PSScriptRoot\..\ProjectInstaller\Release\$fullName" -NewName $installerName
# if($Sign -eq $True)
# {
# Sign Installer
#& "$PSScriptRoot\certificates\certificate.bat" "$PSScriptRoot\..\out\Installer\Release\*.msi"
# Remove pre build event from installer proj file after signing
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:"'
# }
}
主要步骤:
先清理,再生成,最后发布安装包。
重点说明
& $devenvDir "$PSScriptRoot\..\DeviceToolsKit.sln" /project $Installer_proj /Build Release
上述代码,控制Installer项目的采用release模式生成安装包。
$fullName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name
$AppName = (Get-ItemProperty "$PSScriptRoot\..\ProjectInstaller\Release\*.msi").Name.Split('.')[0]
$major_ver, $minor_ver, $patch_ver = GetVersionOfFile $Proj
$targetVersion ="$major_ver.$minor_ver.$patch_ver"
$installerName = $AppName + "_v" + $targetVersion + ".msi"
"Installer Name: $installerName"
Rename-Item -Path "$PSScriptRoot\..\ProjectInstaller\Release\$fullName" -NewName $installerName
上述代码,作用是用命名MSI的安装包,增加版本号尾缀。
但是需要注意,如果你采用了依赖框架的生成方式,那么生成完成后的Setup程序,将无法找到MSI文件。
原因是MSI文件已经被重命名,而负责检查安装环境,并调用MSI的Setup程序,就会找不到原先名字的MSI。
这个重命名的方法,仅适用于不生成Setup程序的发布方式。
有关Installer Setup 的使用,请参考我的其他博客。
里面有详细使用方法和步骤。
注释掉的部分
#[string]$Installer_proj = "$PSScriptRoot\..\ProjectInstaller\ProjectInstaller.vdproj"
#if($Sign -eq $True)
#{
#Add pre build event to sign .exe after rebuilding project but before building installer
#ReplaceLine "$PSScriptRoot\..\src\SPDev\SPDevInstaller\SPDevInstaller.vdproj" '"PreBuildEvent"' '"PreBuildEvent" = "8:call \"$(ProjectDir)/../../../build/certificates/certificate.bat\" \"$(ProjectDir)..\\..\\..\\out\\application_studio_$(Configuration)\\$(Configuration)\\application_studio.exe\"\r\n"'
# }
这个是给安装程序添加证书和签名,没有这两个东西的,就不用这个方法。
通过脚本调用
自动版本号+1
@ECHO OFF
SET ThisScriptsDirectory=%~dp0
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0Build.ps1' -publish_Free_Installer 0 -publish_MSI_Installer 0 -updateVersion 1
pause
修改指定版本号
@ECHO OFF
SET ThisScriptsDirectory=%~dp0
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0Build.ps1' -publish_Free_Installer 0 -publish_MSI_Installer 0 -updateVersion 1 -major_ver 1 -minor_ver 4 -patch_ver 0
pause
发布免安装版本
@ECHO OFF
SET ThisScriptsDirectory=%~dp0
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0Build.ps1' -updateVersion 0 -publish_Free_Installer 1 -publish_MSI_Installer 0
pause
发布MSI安装版本
@ECHO OFF
SET ThisScriptsDirectory=%~dp0
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0Build.ps1' -updateVersion 0 -publish_Free_Installer 0 -publish_MSI_Installer 1
pause