我正在研究自定义的Powershell状态行,并实现了一些很酷的功能:电池监视,WiFi监视等。不幸的是,这些更新往往很慢,因为它们需要调用Get-NetAdapterStatistics,获取wmi对象,和其他非常慢的电话。我正在尝试通过start-job生成子进程,以允许进行后台轮询和更新共享变量,但无法弄清楚该怎么做。我发现最好的替代方法是某种IPC(如此处所述:Pipelining between two SEPARATE Powershell processes),但是如果可能的话,我宁愿使用传统的共享变量。有没有办法做到这一点?我发现最好的选择是将变量作为参数传递,但这不允许轮询。
无需否认,我知道这并不是Powershell的真正目的,但是我仍然想知道这是否有可能。还是编写将返回状态行的c / c ++二进制文件的最佳选择?写入文件(似乎很慢)?如果您有能力或者需要更多信息,请告诉我什么可能有效。谢谢。
更多信息:
Start-Job -Name testJob -Script {
$testVar = "asdf"
}
Write-Host $testVar
# should output asdf
有没有办法做到这一点?我正在尝试做一些工作并返回一个变量。这怎么可能?我发现的唯一可能的方法是:
将文件写入磁盘,这有点慢
使用IPC管道:
$pipe = New-Object System.IO.Pipes.NamedPipeClientStream '.',"testPipe",'In'
Start-Job -Name testJob -Script {
$pipe = New-Object System.IO.Pipes.NamedPipeServerStream "testPipe",'Out'
$pipe.WaitForConnection()
$sw = New-Object System.IO.StreamWriter $pipe
$sw.AutoFlush = $true
$sw.writeLine("foo")
While ($true) {
# do looping and polling, then print stuff
$sw.writeLine($pollResult)
}
$sw.Dispose()
$pipe.Dispose()
}
$pipe.Connect()
$sr = New-Object System.IO.StreamReader $pipe
#when necessary, read info
$output = $sr.ReadLine()
$sr.Dispose()
$pipe.Dispose()
最大的缺点是它有点小故障。最重要的是,当我关闭Powershell窗口时(因为这是一个状态行),我不知道如何关闭IPC管道,并且最终出现“管道泄漏”,导致CPU使用率高和Powershell进程在其中运行。的背景。对于直接后台作业写入文件,至少不是这种情况。显然,当删除最后一个引用时,管道应该关闭,但是后台作业在打开时仍保持运行状态。这是因为在等待与管道相关的内容时(当等待管道连接,完成写线等操作时),powershell会话将挂起无法进行ctrl-c操作的位置。
谢谢,请告诉我是否可以添加更多信息。
更新:我尝试使用空文件基本上作为控制标志(我认为这比为每个设置解析一个文件要快),但是我试图使用作业来返回VCS信息(这样做更容易返回,速度更快)。关于如何解决此问题的任何想法?我很沮丧
注意:我标记了此C#,因为powershell使用C#的管道函数,并且希望有相关知识的人能够提供帮助。
答案 0 :(得分:0)
Boe Prox在这年前做了excellent writeup。他还使用PoshRSJob模块进行了扩展。使用此模块使此操作相当容易。
#Create a synchronized hashtable
$sync = [hashtable]::Synchronized(@{
Time = ''
Stop = $false
Updater = ''
})
#create 5 RSJobs
1..5 | Start-RSJob -ScriptBlock {
param($sync) #accept $sync as a param
$updater = [Guid]::NewGuid() #unique id per job
while(-not $sync.Stop) { #run until told not to
$sync.Time = Get-Date
$sync.Updater = $updater
start-sleep -Seconds 1
}
} -ArgumentList $sync #pass $sync as a param
运行此命令会产生5个工作:
Id Name State HasMoreData HasErrors Command
-- ---- ----- ----------- --------- -------
1 Job1 Running False False ...
2 Job2 Running False False ...
3 Job3 Running False False ...
4 Job4 Running False False ...
5 Job5 Running False False ...
然后,您可以在父进程中检查$ sync,并从这些作业中看到它正在不断更新。请注意,这些不仅是字符串表示形式,而且是完整的对象。
PS C:\> $sync
Name Value
---- -----
Time 4/22/2019 11:58:35 AM
Stop False
Updater 9ab28c51-2941-4866-a064-165b1ceca673
PS C:\> $sync
Name Value
---- -----
Time 4/22/2019 11:58:37 AM
Stop False
Updater 113e78a8-1774-4cdf-9638-7235109f0a0d
要终止作业,我们设置了$sync.Stop = $true
PS C:\> Get-RSJob
Id Name State HasMoreData HasErrors Command
-- ---- ----- ----------- --------- -------
1 Job1 Completed False False ...
2 Job2 Completed False False ...
3 Job3 Completed False False ...
4 Job4 Completed False False ...
5 Job5 Completed False False ...