我正在将MSBuild代码迁移到FAKE - 我无法从fake执行powershell脚本,下面是要用FAKE写的MSBuild文件的代码:
<Target Name="VersionConfig">
<Exec IgnoreExitCode="false" LogStandardErrorAsError="true" StandardErrorImportance="high" Command="powershell -File "$(BuildRoot)\DeployScripts\scripts\AdminScripts\VersionUpdateFile.ps1" -path "$(BuildSolutionVersioningConfig)" -majorVersion "$(BuildNumberMajor)" -minor "$(BuildNumberMinor)" -build "$(BuildNumber)" -revision "$(BuildNumberRevision)""/>
</Target>
如何在FAKE中写这个,我是FAKE的新手并且没有多次使用F#,所以请原谅我,如果这应该是显而易见的。
如果有人可以提供帮助,那将非常有帮助。
谢谢。
答案 0 :(得分:3)
您可以在任何.NET应用程序中使用Powershell pipeline命名空间的类创建System.Management.Automation。您可以使用该管道在本地或远程计算机上执行命令。
以下目标检索进程列表并打印它们。它是PowerShell类的文档示例的F#等价物:
Target "ProcTest" (fun _ ->
PowerShell.Create()
.AddCommand("get-process")
.Invoke()
|> Seq.map(fun result->( result.Properties.["ProcessName"].Value,
result.Properties.["ID"].Value))
|> Seq.iter (fun (name,id)->printfn "%-24O %O" name id)
)
这是一个快速的&amp;我用来在远程服务器上执行命令(特别是巧克力命令)的脏模块。要使它在本地计算机上运行,唯一需要的是删除 ComputerName
参数:
#r "System.Management.Automation"
module MyPowershell =
let InvokeRemote server command =
let block = ScriptBlock.Create(command)
let pipe=PowerShell.Create()
.AddCommand("invoke-command")
pipe.AddParameter("ComputerName", server)
.AddParameter("ScriptBlock", block)
.Invoke()
|> Seq.map (sprintf "%O")
|> Seq.iter (fun line ->
let tracer=if line.Contains("not installed") then
traceError
else
trace
tracer line)
pipe.Streams.Error |> Seq.iter (traceError << sprintf "%O" )
管道由PowerShell类表示。构建它的步骤是:
ScriptBlock
包含我想远程执行的脚本。invoke-command
命令-ComputerName myServer
和-ScriptBlock ...
。 PowerShell错误会发送到Error
流,这样可以更轻松地处理错误。
在本地计算机上执行命令可以简单得多:
let InvokeRemote command =
let pipe=PowerShell.Create()
.AddCommand(command)
pipe.Invoke()
|> Seq.map (sprintf "%O")
|> Seq.iter (fun line ->
let tracer=if line.Contains("not installed") then
traceError
else
trace
tracer line)
pipe.Streams.Error |> Seq.iter (traceError << sprintf "%O" )
答案 1 :(得分:1)
FAKE中的Fake.ProcessHelper
namespace是您正在寻找的。文档不会告诉您这一点,但Fake.ProcessHelper
是marked with the AutoOpen
attribute,这意味着您链接的API参考页中列出的所有函数都可以从您的FAKE构建脚本中获得,而无需任何明确的open
语句来使用它们。你这样使用它:
let inQuotes s = sprintf "\"%s\"" s
Target "Sample" (fun _ ->
let retCode =
ExecProcess
(fun info ->
info.Name <- "powershell.exe" // Don't know if you need full path here
info.WorkingDirectory <- getBuildParam "BuildRoot"
info.Arguments <-
[ "-File"; getBuildParam "BuildRoot" + "\DeployScripts\scripts\AdminScripts\VersionUpdateFile.ps1" |> inQuotes;
"-path"; getBuildParam "BuildSolutionVersioningConfig" |> inQuotes;
"-majorVersion"; getBuildParam "BuildNumberMajor" |> inQuotes;
"-minor"; getBuildParam "BuildNumberMinor" |> inQuotes;
"-build"; getBuildParam "BuildNumber" |> inQuotes;
"-revision"; getBuildParam "BuildNumberRevision" |> inQuotes
] |> separated " "
)
(TimeSpan.FromMinutes 5.0)
if retCode <> 0 then
failwith (sprintf "PowerShell exited with non-zero exit code %d" retCode)
)
一对夫妇注意到:
inQuotes
辅助函数以使info.Arguments
列表看起来更好。separated
function I used。getBuildParam
function I used。