[英]How do I capture .NET trace output from a Powershell job?
I am using a .NET component in Powershell which uses Trace.TraceWarning
, Trace.TraceInformation
etc. 我在Powershell中使用.NET组件,它使用
Trace.TraceWarning
, Trace.TraceInformation
等。
I want to output these traces to the console when I run my Powershell script. 我想在运行Powershell脚本时将这些跟踪输出到控制台。
This works when I use the component in the current session. 当我在当前会话中使用该组件时,这可以工作。 For example (simulating the effect of trace) gives me 'Hello' output to the console:
例如(模拟跟踪的效果)给控制台输出'Hello':
$listener = new-object "system.diagnostics.consoletracelistener"
[System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
[System.Diagnostics.Trace]::TraceInformation("Hello")
But if I do the same within a Powershell job I get no output, even though ConsoleTraceListener should be writing to STDOUT which in turn I expected to get captured by the job. 但是如果我在Powershell工作中做同样的事情,我得不到任何输出,即使ConsoleTraceListener应该写入STDOUT,反过来我希望被工作捕获。 (Interestingly
Console.WriteLine
doesn't work from a job either - but Write-Host
does). (有趣的是,
Console.WriteLine
也不能从作业中运行 - 但是Write-Host
会这样做)。
I am starting my job like so: 我这样开始工作:
$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
It's not clear where you want the captured output to go. 目前尚不清楚您希望捕获的输出去哪里。 Most of the discussion so far revolves around the Console, but since you called it a "job" (I presume you mean Scheduled Task), I'm not so sure the Console is the best place.
到目前为止,大多数讨论围绕着控制台,但由于你把它称为“工作”(我认为你的意思是计划任务),我不太确定控制台是最好的地方。 You'd never see the results.
你永远不会看到结果。 A log file sounds much more appropriate.
日志文件听起来更合适。 If that's the case, you should create a TextWriteTraceLister .
如果是这种情况,您应该创建一个TextWriteTraceLister 。 That will allow you to set a log file for the results.
这将允许您为结果设置日志文件。
Additionally, one of the nice features of Tracing in .Net is that you can have more than one listener attached. 此外,.Net中跟踪的一个很好的功能是你可以连接多个监听器。 So if you want to see the output as it runs, you can also attach the ConsoleTraceListener, and it won't interfere with writing to the log file.
因此,如果您希望在运行时看到输出,您还可以附加ConsoleTraceListener,它不会干扰写入日志文件。
Finally, it's also possible to write your own TraceListener. 最后,还可以编写自己的TraceListener。 This is useful for things like writing to a logging database or web service.
这对于写入日志数据库或Web服务等内容非常有用。 To use your own TraceListener from PowerShell, you would need to build the listener using a .Net language that can be compiled into a class library assembly (dll) that can be deployed to the GAC for use in your project.
要从PowerShell使用自己的TraceListener,您需要使用.Net语言构建侦听器,该语言可以编译为类库程序集(dll),可以部署到GAC以在项目中使用。
I remember running into something similar to this years ago where expected STDOUT and STDIN weren't behaving as expected with start-job and exe's. 我记得遇到类似于今年的事情,预期的STDOUT和STDIN在start-job和exe中没有达到预期的效果。 I ended up using System.Diagnostics.Process and redirecting the STDIN and STDOUT.
我最终使用System.Diagnostics.Process并重定向STDIN和STDOUT。 Here's an example that demonstrates this workaround in a way that may assist you with what you are trying to do.
这是一个示例,以一种可以帮助您完成尝试的方式演示此变通方法。
#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()
}
Output: 输出:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.