- 1 year ago
Golang calls windows.CreateProcessAsUser function how to get Stdout content
Comment
1 / 1
To capture the stdout
of a process launched with windows.CreateProcessAsUser
in Golang, you can use the os/exec
package's Cmd
structure, and set its Stdout
field to a *bytes.Buffer
. Here's an example:
gopackage main
import (
"bytes"
"fmt"
"os/exec"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
func main() {
// Open a handle to the current user's token
var token windows.Token
err := windows.OpenProcessToken(windows.CurrentProcess(), windows.TOKEN_DUPLICATE|windows.TOKEN_QUERY, &token)
if err != nil {
panic(err)
}
defer token.Close()
// Duplicate the token handle for use in CreateProcessAsUser
var dupToken windows.Token
err = windows.DuplicateTokenEx(token, windows.TOKEN_ALL_ACCESS, nil, windows.SecurityImpersonation, windows.TokenPrimary, &dupToken)
if err != nil {
panic(err)
}
defer dupToken.Close()
// Set up the process information struct
var procInfo windows.ProcessInformation
startupInfo := windows.StartupInfo{
CB: uint32(unsafe.Sizeof(windows.StartupInfo{})),
Flags: windows.STARTF_USESTDHANDLES,
StdInput: windows.InvalidHandle,
StdOutput: windows.InvalidHandle,
StdErr: windows.InvalidHandle,
Title: windows.StringToUTF16Ptr("cmd"),
X: 0,
Y: 0,
XSize: 0,
YSize: 0,
XCountChars: 0,
YCountChars: 0,
FillAttribute: 0,
Reserved2: 0,
Reserved: [10]byte{},
ShowWindow: 0,
Reserved3: 0,
hStdInput: 0,
hStdOutput: 0,
hStdError: 0,
}
// Create the process as the duplicated token
cmd := exec.Command("cmd", "/c", "dir")
cmd.SysProcAttr = &syscall.SysProcAttr{
Token: dupToken.Handle,
}
var stdoutBuf bytes.Buffer
cmd.Stdout = &stdoutBuf
err = cmd.Run()
if err != nil {
panic(err)
}
fmt.Printf("stdout: %s", stdoutBuf.String())
}
In this example, we first open a handle to the current user's token, and then duplicate it so that we can use it in CreateProcessAsUser
. We then set up the StartupInfo
structure to specify that we want to use the standard output handle. Finally, we launch the process using exec.Command
and set the Stdout
field of the resulting Cmd
structure to a *bytes.Buffer
. When we call cmd.Run()
, the stdout
output of the process will be captured in the buffer.