Rumah > Artikel > pembangunan bahagian belakang > Menjalankan boleh laku pada baris arahan adalah baik, tetapi menjalankannya melalui program lain mengakibatkan tidak bertindak balas
Hanya jalankan fail boleh laku dan parameter dalam gesaan arahan Windows:
cgx_STATIC.exe -b C:\Users\m3\AppData\Local\Temp\shot-277325955.fbd
Walau bagaimanapun, apabila menjalankan boleh laku yang sama melalui Golang, selepas boleh laku mencipta beberapa fail keluaran, boleh laku laku menjadi tidak bertindak balas.
<code> // Run an executable and print its log into a file. func RunWithLogFile(pthExe string, arg []string, fLog *os.File) error { cmd := exec.Command(pthExe, arg...) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } // Stream logs: // https://stackoverflow.com/a/48849811/3405291 scannerOut := bufio.NewScanner(stdout) scannerErr := bufio.NewScanner(stderr) scannerOut.Split(bufio.ScanRunes) scannerErr.Split(bufio.ScanRunes) for scannerOut.Scan() { _, err = fLog.WriteString(scannerOut.Text()) if err != nil { return err } } for scannerErr.Scan() { _, err = fLog.WriteString(scannerErr.Text()) if err != nil { return err } } if scannerOut.Err() != nil { return err } if scannerErr.Err() != nil { return err } err = cmd.Wait() return err } </code>
Saya tertanya-tanya sama ada terdapat sejenis pepijat dalam kod Go di atas atau ia tidak sesuai untuk menjalankan boleh laku?
Mengikuti cadangan @BurakSerdar, saya membaca dari stdout dan stderr dalam goroutine berasingan, tetapi masalahnya tidak diselesaikan:
<code> // Run an executable and print its log into a file. func RunWithLogFile(pthExe string, arg []string, fLog *os.File) error { cmd := exec.Command(pthExe, arg...) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } var wg sync.WaitGroup wg.Add(2) go streamToLogFile(stdout, fLog, &wg) go streamToLogFile(stderr, fLog, &wg) err = cmd.Start() if err != nil { return err } wg.Wait() err = cmd.Wait() return err } func streamToLogFile(output io.ReadCloser, fLog *os.File, wg *sync.WaitGroup) { defer wg.Done() scanner := bufio.NewScanner(output) scanner.Split(bufio.ScanRunes) for scanner.Scan() { _, err := fLog.WriteString(scanner.Text()) if err != nil { log.Printf("error: write to log file: %s", err.Error()) } } err := scanner.Err() if err != nil { log.Printf("error: write to log file: %s", err.Error()) } } </code>
Menyelesaikan isu tidak bertindak balas dengan menjalankan boleh laku dengan pentadbirkeizinan. Saya melakukan ini:
A C# code runs a Go code and the Go code runs a C Code, i.e. external executable.
C boleh laku memanggil beberapa panggilan OpenGL GLUT. Mungkin mereka perlukan hak admin.
Memulakan kod Go melalui C# menyelesaikan masalah ini seperti berikut: https://www.php.cn/link/ac90e5f00f7542d99231f63fb0dfeecf
<code> public static void RunLogic(string exePath, string args, PostProcess pp) { cmd = new Process(); try { cmd.StartInfo.FileName = exePath; cmd.StartInfo.Arguments = args; cmd.StartInfo.UseShellExecute = true; cmd.StartInfo.CreateNoWindow = false; cmd.StartInfo.RedirectStandardOutput = false; cmd.StartInfo.RedirectStandardError = false; cmd.StartInfo.RedirectStandardInput = false; // Vista or higher check. // https://www.php.cn/link/ac90e5f00f7542d99231f63fb0dfeecf if (System.Environment.OSVersion.Version.Major >= 6) { // Run with admin privileges to avoid a non-responsive executable. cmd.StartInfo.Verb = "runas"; } cmd.EnableRaisingEvents = true; cmd.Exited += new EventHandler(cmd_Exited); cmd.Exited += new EventHandler(pp); cmd.Start(); } catch (Exception ex) { RhinoApp.WriteLine("Error on process start: {0}", ex.Message); } } </code>
Atas ialah kandungan terperinci Menjalankan boleh laku pada baris arahan adalah baik, tetapi menjalankannya melalui program lain mengakibatkan tidak bertindak balas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!