converge/cmd/agent/open_process_windows.go
Erik Brakkee 1ebee30c8c cross compilation on windows working.
pty.Start() is not supported on windows
2024-07-22 19:34:26 +02:00

99 lines
2.3 KiB
Go

package main
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
func example() {
// Create pipes for stdin and stdout
var stdInRead, stdInWrite, stdOutRead, stdOutWrite windows.Handle
sa := &windows.SecurityAttributes{Length: uint32(unsafe.Sizeof(windows.SecurityAttributes{})), InheritHandle: 1}
err := windows.CreatePipe(&stdInRead, &stdInWrite, sa, 0)
if err != nil {
fmt.Println("Error creating stdin pipe:", err)
return
}
defer windows.CloseHandle(stdInRead)
defer windows.CloseHandle(stdInWrite)
err = windows.CreatePipe(&stdOutRead, &stdOutWrite, sa, 0)
if err != nil {
fmt.Println("Error creating stdout pipe:", err)
return
}
defer windows.CloseHandle(stdOutRead)
defer windows.CloseHandle(stdOutWrite)
// Set the pipe to non-blocking mode
mode := uint32(windows.PIPE_NOWAIT)
err = windows.SetNamedPipeHandleState(stdInWrite, &mode, nil, nil)
if err != nil {
fmt.Println("Error setting stdin pipe to non-blocking:", err)
return
}
err = windows.SetNamedPipeHandleState(stdOutRead, &mode, nil, nil)
if err != nil {
fmt.Println("Error setting stdout pipe to non-blocking:", err)
return
}
// Prepare process startup info
si := &windows.StartupInfo{
Cb: uint32(unsafe.Sizeof(windows.StartupInfo{})),
Flags: windows.STARTF_USESTDHANDLES,
StdInput: stdInRead,
StdOutput: stdOutWrite,
StdErr: stdOutWrite,
}
pi := &windows.ProcessInformation{}
// Create the process
cmd := "cmd.exe"
err = windows.CreateProcess(
nil,
syscall.StringToUTF16Ptr(cmd),
nil,
nil,
true,
0,
nil,
nil,
si,
pi,
)
if err != nil {
fmt.Println("Error creating process:", err)
return
}
defer windows.CloseHandle(pi.Process)
defer windows.CloseHandle(pi.Thread)
// Write to the process
message := "echo Hello, World!\r\n"
var written uint32
err = windows.WriteFile(stdInWrite, []byte(message), &written, nil)
if err != nil {
fmt.Println("Error writing to process:", err)
return
}
// Read from the process
buffer := make([]byte, 1024)
var read uint32
err = windows.ReadFile(stdOutRead, buffer, &read, nil)
if err != nil && err != windows.ERROR_NO_DATA {
fmt.Println("Error reading from process:", err)
return
}
fmt.Printf("Output: %s", buffer[:read])
// Wait for the process to finish
windows.WaitForSingleObject(pi.Process, windows.INFINITE)
}