Open Codehardt opened 5 years ago
It isn't clear to me if this is something that the standard library itself should handle, but I recently wrote some Go code to do just this if it helps: https://github.com/WireGuard/wgctrl-go/blob/master/internal/wguser/conn_windows.go#L196.
/cc @alexbrainman
Or sure, maybe we could fix that code.
I don't have time to debug this, but, if someone is interested, maybe they could make code above work. Maybe FindFirstFile and FindNextFile could be used to read that directory.
Alex
Change https://golang.org/cl/181057 mentions this issue: os: treat the Windows named pipe root as a directory
Maybe FindFirstFile and FindNextFile could be used to read that directory.
Thanks, this solved my issue.
I've submitted a patch that makes this work with package os
, but it needs a bit more work and it probably won't land until Go 1.14 at this point.
Documentation states explicitly that it is not possible to list pipes using Win 32 API. For the same reason, >dir \\.\\pipe\\
does not return anything but an error.
The same documentation suggests to use NtQueryDirectoryFile
of library NtosKrnl
which is unavailable in the syscall
package.
For completeness, the Powershell instruction to list pipes on Windows is [System.IO.Directory]::GetFiles("\\.\\pipe\\")
. The directory value is currently not supported by the files method which uses FindFirstFileW
.
Adding the relevant call require seems more like a proposal.
It isn't clear to me if this is something that the standard library itself should handle, but I recently wrote some Go code to do just this if it helps: https://github.com/WireGuard/wgctrl-go/blob/master/internal/wguser/conn_windows.go#L196.
@mdlayher the code you are referring to, implements functionality to connect to Windows named pipe. What we want in this issue is to list all files under \\.\pipe
. Not the same thing.
The same documentation suggests to use
NtQueryDirectoryFile
of libraryNtosKrnl
which is unavailable in thesyscall
package. ... Adding the relevant call require seems more like a proposal.
@iWdGo using NtQueryDirectoryFile sounds like it might work. And you don't need to add NtQueryDirectoryFile to syscall package. We can put it in internal/syscall/windows if it works.
Alex
Following code can help until fixed.
// List pipes on Windows
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
"syscall"
)
// https://github.com/golang/go/issues/32423
const (
windows10Pipes = "\\\\.\\pipe\\\\"
)
func cmdListPipes() (pipes []string, err error ) {
cmd := exec.Command("cmd")
out := new(bytes.Buffer)
cmd.Stdout = out
cmd.Stderr = out
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: false,
CmdLine: "/C \"dir " + windows10Pipes + " /B \" ",
CreationFlags: 0,
Token: 0,
ProcessAttributes: nil,
ThreadAttributes: nil,
}
err = cmd.Run()
if err != nil {
fmt.Errorf("%v", err)
if cmd.Stderr != nil {
out, _ := cmd.CombinedOutput()
log.Fatalf("%s", out)
}
}
return strings.Split(out.String(), "\n"), nil
}
func main() {
pipes, err := cmdListPipes()
if err != nil {
fmt.Println(err)
}
for _, p := range pipes {
fmt.Println(p)
}
if len(pipes) == 0 {
fmt.Println("no output")
}
}
The issue here is that Windows is not treating \\.\pipe
in the same way as \\.\pipe\
(notice the trailing slash). You can iterate over the later, but not over the former. In fact, using go1.21.1 I can iterate over all the named pipes if opening the root with os.Open(\\.\pipe\
).
This behavior is weird, can't see it documented anywhere, but it is what it is. Python's os.listdir(r'\\.\pipe')
work because they call FindFirstFileW(r'\\.\pipe\*')
under the hood.
We could special-case \\.\pipe
in os.Open
so it opens \\.\pipe\
instead, but I don't know the implications, documentation lacking.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I wanted to iterate over Windows' named pipes using
os
package:What did you expect to see?
The same result as in Python:
What did you see instead?