I am working on a custom powershell statusline, and implemented a couple cool features: battery monitoring, wifi monitoring, etc. Unfortunately, these tend to be slow to update, as they require calls to Get-NetAdapterStatistics, getting wmi objects, and other very slow calls. I am trying to spawn child processes via start-job to allow for background polling and updating a shared variable, but can't figure out how to do this. The best possible substitute I have found is a sort of IPC (as described here: Pipelining between two SEPARATE Powershell processes), but I'd prefer to stick with a traditional shared variable if possible. Is there a way to do this? The best alternative I've found is passing variables as arguments, but this won't allow for polling.
To disclaim, I am aware this is not really what powershell is designed for, but I am still wondering if this is possible. Or is the best option to write a c/c++ binary that will return the statusline? Write to a file (this seems like it might be slow)? Let me know what might work, if you are able, or if you need more information. Thank you.
More information:
Start-Job -Name testJob -Script {
$testVar = "asdf"
}
Write-Host $testVar
# should output asdf
Is there any way to do this? I am trying to do some work and return a variable. How is this possible? The only possible ways I have found are:
Write a file to the disk, which is a bit slow
Use an IPC pipe:
$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()
The biggest downside to this is that it's a bit glitchy. Most importantly, I don't know how to shut down the IPC pipe when I close the powershell window (as this is a statusline) and I end up with a "pipe-leak" that leads to high cpu usage and powershell processes running in the background. This is at least not the case with the straight background job writing to a file. Apparently the pipe is supposed to close when the last reference is deleted, but the background job keeps running with it open. This is because a powershell session will hang to the point where it cannot be ctrl-c'd when it's waiting for something pipe-related (when waiting for pipe connect, to finish writing a line, etc.).
Thank you, and please let me know if I can add any more information.
Update: I've tried using empty files basically as control flags (I think it would be faster than parsing one file for each setting), but am trying to use a job to return VCS information (which would be easier to just return, and faster). Any ideas on how to solve this issue? I'm stumped.
Note: I tagged this C# because powershell uses C#'s pipe functions, and I'm hoping someone with knowledge thereof might be able to help.