8

我在 Powershell 中使用 .NET 组件,它使用 .NETTrace.TraceWarningTrace.TraceInformation

当我运行我的 Powershell 脚本时,我想将这些跟踪输出到控制台。

这在我在当前会话中使用组件时有效。例如(模拟跟踪的效果)给我 'Hello' 输出到控制台:

 $listener = new-object "system.diagnostics.consoletracelistener"
 [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
 [System.Diagnostics.Trace]::TraceInformation("Hello")

但是,如果我在 Powershell 作业中做同样的事情,我不会得到任何输出,即使 ConsoleTraceListener 应该写入 STDOUT,而我又希望被作业捕获。(有趣Console.WriteLine的是,也不能从工作中工作——但Write-Host确实如此)。

我开始我的工作是这样的:

$work = {
     $listener = new-object "system.diagnostics.consoletracelistener"
     [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
     [System.Diagnostics.Trace]::TraceInformation("Hello")
}
$job = Start-Job -RunAs32 -ScriptBlock $work
$job | Receive-Job -Wait
4

2 回答 2

1

我记得在几年前遇到过类似的情况,预期的 STDOUT 和 STDIN 在 start-job 和 exe 中的表现不如预期。我最终使用了 System.Diagnostics.Process 并重定向了 STDIN 和 STDOUT。这是一个示例,它以一种可以帮助您尝试执行的操作的方式演示此解决方法。

#added extra trace messages with Get-Date and implemented a random delay for demo purpose
$work = {
     $listener = new-object "system.diagnostics.consoletracelistener"
     [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
     1..10 | % {
         Start-Sleep $(Get-Random 5)
         [System.Diagnostics.Trace]::TraceInformation((Get-Date))
    }
}
#Create a process
$process = New-Object System.Diagnostics.Process 
$process.StartInfo.UseShellExecute = $false
#redirect stdout
$process.StartInfo.RedirectStandardOutput = $true
#call powershell
$process.StartInfo.FileName = "powershell.exe"
#pass the $work scriptblock
$process.StartInfo.Arguments = "-noprofile -command $work"
#start the process
$process.Start() | Out-Null
#readlines as they come in and exit when process is done
while(-not $process.HasExited){
    $process.StandardOutput.ReadLine()
}

输出:

powershell.exe Information: 0 : 01/30/2015 12:27:17
powershell.exe Information: 0 : 01/30/2015 12:27:20
powershell.exe Information: 0 : 01/30/2015 12:27:21
powershell.exe Information: 0 : 01/30/2015 12:27:25
powershell.exe Information: 0 : 01/30/2015 12:27:26
powershell.exe Information: 0 : 01/30/2015 12:27:28
powershell.exe Information: 0 : 01/30/2015 12:27:29
powershell.exe Information: 0 : 01/30/2015 12:27:33
powershell.exe Information: 0 : 01/30/2015 12:27:36
powershell.exe Information: 0 : 01/30/2015 12:27:40
于 2015-01-30T03:30:24.893 回答
-1

目前尚不清楚您希望捕获的输出去哪里。到目前为止,大多数讨论都围绕控制台展开,但是由于您将其称为“工作”(我认为您的意思是计划任务),因此我不确定控制台是否是最佳位置。你永远不会看到结果。日志文件听起来更合适。如果是这种情况,您应该创建一个TextWriteTraceLister。这将允许您为结果设置日志文件。

此外,.Net 中的 Tracing 的一大优点是您可以连接多个侦听器。因此,如果您想在运行时查看输出,还可以附加 ConsoleTraceListener,它不会干扰写入日志文件。

最后,也可以编写自己的 TraceListener。这对于写入日志数据库或 Web 服务等事情很有用。要在 PowerShell 中使用您自己的 TraceListener,您需要使用 .Net 语言构建侦听器,该语言可以编译成类库程序集 (dll),可以部署到 GAC 以在您的项目中使用。

于 2015-01-29T15:06:46.127 回答