为了在服务器上自动编译发布,特意搞了个ps脚本,中间遇到不少坑,希望可以帮到大家解决相关问题。
先上脚本
···
#build_fun.ps1
function global:copy-bin($src, $dest, $buildType)
{
pwd
echo "xcopy `"$src\bin\$buildType\.`" `"$dest\`" /e /y /d /EXCLUDE:copyExcludeBin.txt"
xcopy "$src\bin\$buildType\." "$dest\" /e /y /d /EXCLUDE:copyExcludeBin.txt
pwd
}
function global:Build-VisualStudioSolution ($SolutionFilePath, $Configuration, $CleanFirst, $Platform )
{
# Local Variables
$MsBuild = $env:systemroot + "\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe";
# Local Variables
$fileinfo = ([System.IO.FileInfo]$SolutionFilePath) ;
$SolutionFile = $fileinfo.Name;
$BuildOutput = "BuildLogOutput.txt";
$BuildLogFile= $fileinfo.DirectoryName + "\msbuild.log"; # 这个名字是对应 /fl1
$bOk = $true;
write-host "SolutionFilePath : $SolutionFilePath";
write-host "SolutionFile : $SolutionFile";
write-host "BuildLog : $BuildOutput";
write-host "BuildLogFile : $BuildLogFile";
try
{
# Clear first?
if($CleanFirst)
{
write-host CleanFirst
&$MsBuild $SolutionFilePath /t:clean /p:Configuration=$Configuration/v:minimal
}
write-host "Building..."
$MsBuildArgs = "/p:Configuration=$Configuration"
if ($Platform)
{
$Platform += ("/p:Platform="""+$Platform+"""")
}
#/nologo
&$MsBuild $SolutionFilePath /t:build $Platform $MsBuildArgs /verbosity:normal /clp:ShowEventId /flp:"Summary;Verbosity=normal;LogFile=$BuildLogFile"
$ret = $?;
echo "MsBuild 编译=$ret";
if ($ret)
{
#echo "MsBuild 编译成功";
$bOk = $true;
}
else
{
#echo "MsBuild 编译失败";
$bOk = $false;
}
}
catch
{
$bOk = $false;
Write-Error ("Unexpect error occured while building " + $SolutionFile + ": " + $_.Exception.Message);
}
# All good so far?
if($bOk)
{
#Show projects which where built in the solution
#Select-String -Path $BuildOutput -Pattern "Done building project" -SimpleMatch
# Show if build succeeded or failed...
#echo $BuildLogFile;
$successes = Select-String -Path $BuildLogFile -Pattern "已成功生成" -SimpleMatch -Encoding default
$failures = Select-String -Path $BuildLogFile -Pattern "生成失败" -SimpleMatch -Encoding default
if($failures -ne $null)
{
#Write-Warning ($SolutionFile + ": A build failure occured. Please check the build log $BuildOutput for details.");
}
#echo "successes = $successes" ;
#echo "failures = $failures" ;
if($successes -and !$failures )
{
$global:ret = "ok";
return "ok";
}
}
}
#$ret = Build-VisualStudioSolution -SolutionFilePath "E:\src-temp\xxxxx" -Configuration "Debug" ;
#if ($ret = "ok")
#{
# copy-bin "E:\src-temp\ConsoleApplication1\ConsoleApplication1" "E:\src-temp\ConsoleApplication1\build\" "debug"
#}
# end build_fun.ps1
# make.ps1
echo 准备VS环境
$vs = “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat”
&$vs
# 获取编译函数
#不要忘了命令开始的点和中间的空格:“来自点后”的文件请确保它们全部的变量和函数有定义在被调用的脚本里面同时在脚本执行时不能删除它。
#. "$PSScriptRoot\build_fun.ps1"
.\build_fun.ps1
$tf = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\tf.exe"
echo 切换TFS工作区
# 加了登录信息会提示 指定的项过多的错误 /login:yx\yeab,"abc123"
&$tf workspaces /collection:http://172.16.1.2:8080/DevelopmentCollection src_temp
$tf_path="\$/Conv/Source/Branches/201708"
$local_path="F:\src-temp\Conv\road"
echo "开始更新 \$tf_path"
&$tf get $local_path /force #/recursive
#客户端
$global:ret = 0
Build-VisualStudioSolution "F:\src-temp\Conv\road\Foreground\Foreground.sln" "Debug" \$false
if ($ret -eq "ok")
{
xcopy "F:\src-temp\Conv\road\Foreground\H2010Client\." "F:\src-temp\Conv_publish\02.Client\" /e /y /d
}
#服务器端
$global:ret = 0
Build-VisualStudioSolution "F:\src-temp\Conv\road\Server\Server.sln" "Debug" \$false
if ($ret -eq "ok")
{
copy-bin "F:\src-temp\Conv\road\Server" "F:\src-temp\publish\01.Server"
}
···
坑1 调用路径有空格的脚本
如果是普通文件 ,如 abc.bat,那么 c:\abc.bat 就可以调用了。
但如果是C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat,你就要加双引号。但如果你就写成
“C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat”
powershell 会给你打印这个字符串,而不是执行。
这时候你要 用点 . 或 & 符号来调用
. “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat”
&”C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat”坑2 调用其他脚本的函数
为了脚本重用,我们会把函数写在独立的文件中,但函数默认只在当前脚本生效,为了达到效果,函数要定义为 global
如:function global:myFun1(xxxx)坑3 函数里面的输出没有了
如果调用方获取了返回值,函数里面的输出,都会到了那个返回值里,而不再显示在屏幕,除非你用 write-host
···
function myFun1()
{
echo ‘ok’
}
$ret = myFun1 # 这里 ret 会变成 ok,而屏幕不输出
myFun1 # 就这么调用,屏幕才会显示 ok
···坑4 msbuild 错误
”’
$MsBuildArgs = “$SolutionFilePath /t:build /verbosity:normal /clp:ShowEventId /flp:”“Summary;Verbosity=normal;LogFile=$BuildLogFile”” /p:Configuration=$Configuration /p:VisualStudioVersion=12.0 /p:Platform=$Platform”
\&$MsBuild $MsBuildArgs
”’
输出是这样
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe F:\src-temp\Conv\road\Foreground\Foreground.sln /t:build /verbosity:normal /clp:ShowEventId /flp:Summary;Verbosity=normal;LogFile=F:\src-temp\Conv\road\Foreground\msbuil
d.log /p:Configuration=Debug /p:VisualStudioVersion=12.0 /p:Platform=”Any CPU”
命令行执行没问题,但 powershell执行却报错
MSBUILD : error MSB1008: 只能指定一个项目。
开关: CPU
如果用x86是没问题
貌似powershell 把 “Any CPU” 解析为2个内容了。
解决方法:把参数一个一个写
”’
&$MsBuild $SolutionFilePath /t:build $Platform $MsBuildArgs /verbosity:normal /clp:ShowEventId /flp:”“Summary;Verbosity=normal;LogFile=$BuildLogFile”
”’