agent/session/shell/shell_windows.go (101 lines of code) (raw):

package shell import ( "context" "fmt" "os" "path/filepath" "strings" "github.com/aliyun/aliyun_assist_client/agent/session/channel" "github.com/aliyun/aliyun_assist_client/agent/session/winpty" "github.com/aliyun/aliyun_assist_client/common/pathutil" "github.com/aliyun/aliyun_assist_client/thirdparty/sirupsen/logrus" ) const ( defaultConsoleCol = 200 defaultConsoleRow = 60 ) type ShellPlugin struct { id string stdin *os.File stdout *os.File pty *winpty.WinPTY cmdContent string username string passwordName string dataChannel channel.ISessionChannel first_ws_col uint32 first_ws_row uint32 sendInterval int exitCtx context.Context exitFunc context.CancelCauseFunc logger logrus.FieldLogger } func StartPty(plugin *ShellPlugin) (err error) { finalCmd := "powershell.exe" if plugin.cmdContent != "" { finalCmd = plugin.cmdContent } plugin.logger.Infoln("finalCmd ", finalCmd) exe_path, err := pathutil.GetExecutableDir() if err != nil { return fmt.Errorf("failed to determine executable directory: %w", err) } winptyDllFilePath := filepath.Join(exe_path, "plugin", "SessionManager", "winpty.dll") var pty *winpty.WinPTY if plugin.username == "" { pty, err = winpty.Start(winptyDllFilePath, finalCmd, defaultConsoleCol, defaultConsoleRow, winpty.DEFAULT_WINPTY_FLAGS) if err != nil { plugin.logger.Errorln("error in winpty.Start") return err } } else { plugin.logger.Errorln("not support") return fmt.Errorf("not support") } plugin.pty = pty plugin.stdin = pty.StdIn plugin.stdout = pty.StdOut if plugin.first_ws_col != 0 { plugin.SetSize(plugin.first_ws_col, plugin.first_ws_row) } return err } func (p *ShellPlugin) startPtyAsUser(user string, pass string, shellCmd string) (err error) { return nil } func (p *ShellPlugin) waitPid() { } func (p *ShellPlugin) stop() (err error) { p.logger.Info("Stopping winpty") if p.pty == nil { return nil } if err = p.pty.Close(); err != nil { return fmt.Errorf("Stop winpty failed: %s", err) } return nil } func (p *ShellPlugin) SetSize(ws_col, ws_row uint32) (err error) { if p.pty == nil { p.first_ws_col = ws_col p.first_ws_row = ws_row return nil } if err = p.pty.SetSize(ws_col, ws_row); err != nil { return fmt.Errorf("Set winpty size failed: %s", err) } return nil } func (p *ShellPlugin) onInputStreamData(payload []byte) error { // deal with powershell nextline issue https://github.com/lzybkr/PSReadLine/issues/579 payloadString := string(payload) if strings.Contains(payloadString, "\r\n") { // From windows machine, do nothing } else if strings.Contains(payloadString, "\n") { // From linux machine, replace \n with \r num := strings.Index(payloadString, "\n") payloadString = strings.Replace(payloadString, "\n", "\r", num-1) } if _, err := p.stdin.Write([]byte(payloadString)); err != nil { p.logger.Errorf("Unable to write to stdin, err: %v.", err) return err } return nil }