Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Powershell作业捕获.NET跟踪输出?_Powershell_Trace_Powershell Jobs - Fatal编程技术网

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

如何从Powershell作业捕获.NET跟踪输出?,powershell,trace,powershell-jobs,Powershell,Trace,Powershell Jobs,我正在Powershell中使用一个.NET组件,它使用跟踪.TraceWarning,跟踪.TraceInformation等 我希望在运行Powershell脚本时将这些跟踪输出到控制台 当我在当前会话中使用该组件时,这种方法有效。例如(模拟跟踪效果)向控制台提供“Hello”输出: $listener = new-object "system.diagnostics.consoletracelistener" [System.Diagnostics.Trace]::Listeners.

我正在Powershell中使用一个.NET组件,它使用
跟踪.TraceWarning
跟踪.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

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

此外,在.Net中跟踪的一个很好的特性是,可以连接多个侦听器。因此,如果希望在输出运行时查看输出,还可以附加ConsoleTraceListener,这样就不会干扰对日志文件的写入


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

我记得几年前遇到过类似的情况,其中预期的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

ConsoleTraceListener写入控制台,因此相关:ConsoleTraceListener似乎写入标准输出。但是由于工作的原因,在经过更多的测试后,我发现了一些关于工作和儿童工作的有趣的事情。我认为最终的问题是powershell没有使用System.Console类,而是使用自定义System.Management.Automation.Host.PSHost类并重定向流。但在某些边缘情况下,如您的情况下,这似乎并没有按预期实现。ConsoleTraceListener只是使用标准输出。我不知道这是怎么回事!这是一个powershell作业,就像在用Start job启动的东西中一样。顺便说一句,我之所以使用作业,是因为我需要从64位powershell加载并使用x86.NET程序集。Job提供了一种非常简单的方法,可以在常规psh会话中运行跟踪语句时将输出放入管道中。因此,理想情况下,它们将以与正常输出结果相同的方式从receive job命令返回。您可能会发现这很有帮助:谢谢,但不确定.NET跟踪的解释是否真的对我有帮助。我对它相当熟悉。我曾考虑编写一个自定义跟踪侦听器来钩住事件,并将它们输出到PSH中我知道可以工作的部分,例如write host,但我希望得到一个明确的答案,解释为什么问题中的场景不起作用。这相当于理论物理学家的标准借口。我们不再说“因为量子”,而是说“因为线程”。开始作业将工作推送到单独的线程中,跟踪事件仍然在单独的线程中触发。每个线程都有自己的隐藏标准输出。Start Job保留这些结果,并最终通过Receive Job将其推回。对于跟踪事件。。。看起来不是那么多,至少在这种情况下。谢谢你的回答,但是我认为开始过程是“欺骗”。我想弄明白为什么它对乔布斯不起作用