Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Menjalankan boleh laku pada baris arahan adalah baik, tetapi menjalankannya melalui program lain mengakibatkan tidak bertindak balas

Menjalankan boleh laku pada baris arahan adalah baik, tetapi menjalankannya melalui program lain mengakibatkan tidak bertindak balas

WBOY
WBOYke hadapan
2024-02-08 20:42:101003semak imbas

Menjalankan boleh laku pada baris arahan adalah baik, tetapi menjalankannya melalui program lain mengakibatkan tidak bertindak balas

Kandungan soalan

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?

Groutine tunggal

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>

Jawapan betul


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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam