'Update a WPF text box with stdout redirected from another process [duplicate]

I have a WPF application in which I am starting a Powershell process and redirecting the standard output to a textbox. I am facing a problem in which when the Powershell process is started, the Powershell window opens up but stays blank. The process is executing in the background however, the textbox is only updated when the Powershell window is closed. I would like for the text box to update and the process to move forward simultaneously.

How can I achieve this? My code is like this:

private async void btnStartPowershell(object sender, RoutedEventArgs e)
{
    string powershellPath = @"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
    Thread psThread = new Thread(() =>
    {
        string cOut = OpenPowershell(powershellPath, Installer, logPath, "Config Builder");
        if (cOut.Contains("error"))
        {
            ErrorStatusStack.Visibility = Visibility.Visible;
        }
        Action action = () => doUIUpgrade(cOut, logPath);
        this.BeginInvoke(action);
    });
    psThread.Start();
    txtboxCompletedProcess.Text = $"Powershell Scripts Completed. Please see the logs for details.";
}

private void doUIUpgrade(string cOut, string logPath)
{
    PSOutputTextBlock.Text = cOut;
    if (cOut.Contains("OCMS INSTALLATION STARTED"))
    {
        Console.WriteLine("YES");
    }
    InstallationStartedTextBlock.Text = $"Installation started. Please do not close this window. More details can be found at {logPath}";
}

private string OpenPowershell(string path, string script)
{
        try
        {
            bool is64 = IntPtr.Size == 8;
            var ENV = "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* "
                   + (is64 ? ",HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*" : "")
                   + " | Select-Object DisplayName";
            ProcessStartInfo startPowershell = new ProcessStartInfo(path, ENV);
            startPowershell.UseShellExecute = false;
            startPowershell.Arguments = script;
            startPowershell.RedirectStandardOutput = true;
            startPowershell.EnvironmentVariables.Add("RedirectStandardOutput", "true");
            startPowershell.EnvironmentVariables.Add("RedirectStandardError", "true");
            startPowershell.EnvironmentVariables.Add("UseShellExecute", "false");
            startPowershell.EnvironmentVariables.Add("CreateNoWindow", "true");
            Process psProcess = Process.Start(startPowershell);
            string output = psProcess.StandardOutput.ReadToEnd();
            psProcess.WaitForExit();
            return output;
        }
        catch (Exception error)
        {
            MessageBox.Show(error.Message);
            return error.ToString();
        }
}

I have tried doing string output = psProcess.StandardOutput.ReadLine(); instead of string output = psProcess.StandardOutput.ReadToEnd(); but I still only get the text box updated when the entire script is completed and not before.

I'll appreciate any help here.



Solution 1:[1]

you should create another thread for your psProcess's getting stdout and update by timers. it could helps you

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1