99 lines
2.3 KiB
Go
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)
|
|
}
|