96 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//go:build windows
 | 
						|
 | 
						|
package pty
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"io/ioutil"
 | 
						|
	"log"
 | 
						|
	"net/http"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"path/filepath"
 | 
						|
	"runtime"
 | 
						|
 | 
						|
	"github.com/artdarek/go-unzip"
 | 
						|
	"github.com/iamacarpet/go-winpty"
 | 
						|
)
 | 
						|
 | 
						|
type Pty struct {
 | 
						|
	tty *winpty.WinPTY
 | 
						|
}
 | 
						|
 | 
						|
func DownloadDependency() {
 | 
						|
	resp, err := http.Get("https://dn-dao-github-mirror.daocloud.io/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip")
 | 
						|
	if err != nil {
 | 
						|
		log.Println("wintty 下载失败", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	defer resp.Body.Close()
 | 
						|
	content, err := ioutil.ReadAll(resp.Body)
 | 
						|
	if err != nil {
 | 
						|
		log.Println("wintty 下载失败", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if err := ioutil.WriteFile("./wintty.zip", content, os.FileMode(0777)); err != nil {
 | 
						|
		log.Println("wintty 写入失败", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if err := unzip.New("./wintty.zip", "./wintty").Extract(); err != nil {
 | 
						|
		fmt.Println("wintty 解压失败", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	arch := "x64"
 | 
						|
	if runtime.GOARCH != "amd64" {
 | 
						|
		arch = "ia32"
 | 
						|
	}
 | 
						|
	executablePath, err := getExecutableFilePath()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println("wintty 获取文件路径失败", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	os.Rename("./wintty/"+arch+"/bin/winpty-agent.exe", filepath.Join(executablePath, "winpty-agent.exe"))
 | 
						|
	os.Rename("./wintty/"+arch+"/bin/winpty.dll", filepath.Join(executablePath, "winpty.dll"))
 | 
						|
	os.RemoveAll("./wintty")
 | 
						|
	os.RemoveAll("./wintty.zip")
 | 
						|
}
 | 
						|
 | 
						|
func getExecutableFilePath() (string, error) {
 | 
						|
	ex, err := os.Executable()
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	return filepath.Dir(ex), nil
 | 
						|
}
 | 
						|
 | 
						|
func Start() (*Pty, error) {
 | 
						|
	shellPath, err := exec.LookPath("powershell.exe")
 | 
						|
	if err != nil || shellPath == "" {
 | 
						|
		shellPath = "cmd.exe"
 | 
						|
	}
 | 
						|
	path, err := getExecutableFilePath()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	tty, err := winpty.OpenDefault(path, shellPath)
 | 
						|
	return &Pty{tty: tty}, err
 | 
						|
}
 | 
						|
 | 
						|
func (pty *Pty) Write(p []byte) (n int, err error) {
 | 
						|
	return pty.tty.StdIn.Write(p)
 | 
						|
}
 | 
						|
 | 
						|
func (pty *Pty) Read(p []byte) (n int, err error) {
 | 
						|
	return pty.tty.StdOut.Read(p)
 | 
						|
}
 | 
						|
 | 
						|
func (pty *Pty) Setsize(cols, rows uint32) error {
 | 
						|
	pty.tty.SetSize(cols, rows)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (pty *Pty) Close() error {
 | 
						|
	pty.tty.Close()
 | 
						|
	return nil
 | 
						|
}
 |