ddnet/scripts/send_named_pipe.ps1
Robert Müller 1604784669 Improve Windows pipe (FIFO) support
Use `WaitForPipeDrain` to deterministically wait for the pipe to drain instead of using `Start-Sleep`.

Use `Dispose` instead of `Close` to properly flush and close the pipe stream.

Add error handling for connection timeout and I/O errors.

Handle `ERROR_BROKEN_PIPE` separately when peeking at pipe, as this happens when the pipe is disconnected immediately after connecting it or after reading the previous message.

Don't ignore `ERROR_BAD_PIPE` anymore, as the pipe should never be in a disconnected (i.e. bad) state at this point of the function.
2023-09-05 19:15:09 +02:00

42 lines
1.3 KiB
PowerShell

# This PowerShell script connects to a Named Pipe server,
# sends one message and then disconnects again.
# The first argument is the name of the pipe.
# The second argument is the message to send.
if ($args.length -lt 2) {
Write-Output "Usage: ./send_named_pipe.ps1 <pipename> <message> [message] ... [message]"
exit -1
}
$Wrapper = [pscustomobject]@{
Pipe = new-object System.IO.Pipes.NamedPipeClientStream(
".",
$args[0],
[System.IO.Pipes.PipeDirection]::InOut,
[System.IO.Pipes.PipeOptions]::None,
[System.Security.Principal.TokenImpersonationLevel]::Impersonation
)
Reader = $null
Writer = $null
}
try {
$Wrapper.Pipe.Connect(5000)
$Wrapper.Reader = New-Object System.IO.StreamReader($Wrapper.Pipe)
$Wrapper.Writer = New-Object System.IO.StreamWriter($Wrapper.Pipe)
$Wrapper.Writer.AutoFlush = $true
for ($i = 1; $i -lt $args.length; $i++) {
$Wrapper.Writer.WriteLine($args[$i])
}
# Wait for pipe contents to be read.
$Wrapper.Pipe.WaitForPipeDrain()
# Dispose the pipe, which also calls Flush and Close.
$Wrapper.Pipe.Dispose()
# Explicity set error level 0 for success, as otherwise the current error level is kept.
exit 0
} catch [TimeoutException] {
Write-Output "Timeout connecting to pipe"
exit 1
} catch [System.IO.IOException] {
Write-Output "Broken pipe"
exit 2
}