简体   繁体   English

如何从Powershell作业捕获.NET跟踪输出?

[英]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.TraceWarningTrace.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.

相关问题 如何将输出从 PowerShell 中的外部进程捕获到变量中? - How do I capture the output into a variable from an external process in PowerShell? 如何在 VSCode 中获得完整的 PowerShell 脚本跟踪输出? - How do I get a complete PowerShell script trace output in VSCode? 如何在GUI主窗口中显示Powershell作业的输出? - How do I show output of powershell job in main GUI window? 如何从Powershell重定向输出 - How Do I Redirect Output From Powershell Powershell:如何捕获主机的输出 - Powershell: How to capture output from the host 如何在PowerShell中从列表框捕获所选值? - How do I capture the selected value from a ListBox in PowerShell? Powershell:如何捕获PowerShell输出 - Powershell : How to capture powershell output Powershell 后台作业 - 如何使用“ComputerName”参数从 Export-Counter/Get-Counter 获取输出? - Powershell Background Job - How do I get output from Export-Counter/Get-Counter with 'ComputerName' parameter? 捕获从.NET应用程序执行的powershell脚本的标准输出 - Capture standart output of powershell script executed from .NET application 为什么从开始作业与仅运行代码相比,我在 Powershell 中得到不同的 output? - Why do I get different output in Powershell from start-job vs just running the code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM