Progressbar 的进程安装无法正常工作

Process installation with Progressbar not working properly

我知道我将进程放在 for 循环中的方法不正确,我只是想知道如何通过安装更新​​进度条,进度条相应地更新进程安装。当安装开始时进度条在我的情况下在后台安装 运行 后更新。

void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressbar1.Value = e.ProgressPercentage;
        }

        void _bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                this.textblock1.Text = "Completed";
            }
            else if (!(e.Error == null))
            {
                this.textblock1.Text = ("Error :" + e.Error.Message);
            }
            else
            {
                progressbar1.Maximum = 100;
                progressbar1.Minimum = 1;
                progressbar1.Value = progressbar1.Maximum;
                textblock1.Text = "Completed";
            }

        }

  private readonly BackgroundWorker _bw = new BackgroundWorker();
        public ControlPanelFinal()
        {
            InitializeComponent();
            SilverLightInstall();
            _bw.DoWork += _bw_DoWork;
            _bw.RunWorkerCompleted += _bw_RunWorkerCompleted;
            _bw.ProgressChanged += _bw_ProgressChanged;
            _bw.WorkerReportsProgress = true;
        }

void _bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 100; i++)
            {
                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(100);
       }

                string filepath = Path.Combine(Path.GetTempPath(), "Silverlight.exe");
                Process p = new Process();
                p.StartInfo.FileName = filepath;
                p.StartInfo.Arguments = string.Format(" /q  /i \"{0}\" ALLUSERS=1", filepath);
                p.StartInfo.Verb = "runas";
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                p.Start();

}

您是否可以这样做取决于您的 Silverlight 进程实际在做什么以及它本身是否提供任何进度通知,例如通过写入标准输出或为目的。

例如,如果进程确实写入 stdout,您可以这样做:

void _bw_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker)sender;

    string filepath = Path.Combine(Path.GetTempPath(), "Silverlight.exe");
    Process p = new Process();
    p.StartInfo.FileName = filepath;
    p.StartInfo.Arguments = string.Format(" /q  /i \"{0}\" ALLUSERS=1", filepath);
    p.StartInfo.Verb = "runas";
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.UseShellExecute = false;
    p.Start();

    string line;

    while ((line = p.StandardOutput.ReadLine()) != null)
    {
        worker.ReportProgress(ConvertStdoutToProgress(line));
    }
}

其中 ConvertStdoutToProgress() 方法是您编写的某种假设方法,可以解释流程的一行输出并将其转换为某个百分比进度值。

(注意:重定向 stdout 以便您可以阅读它需要将 UseShellExecute 设置为 false,但这可能会干扰您的场景。我看到您正在设置 Verb 属性,如果不将 UseShellExecute 设置为 true,我不确定是否可以使用它。如果不是,那么显然你不能使用 stdout 重定向来取得进展。但你可能不会无论如何都可以……以上只是一个说明基本技术的示例;无论如何,您都必须根据自己的具体情况对其进行自定义。

如果您没有办法从流程中可靠地检索进度信息,那么最好的方法是根本不要尝试指示真正的进度。您仍然可以使用 ProgressBar,但将 Style 属性 设置为 ProgressBarStyle.Marquee。这将导致 ProgressBar 显示 activity 的动画指示(具体指示因平台而异,但这通常是一个填充条,带有周期性移动的动画突出显示)。

可以在开始这个过程后设置一个带有计时器的循环,将进度伪造到一个点(你不会'想要显示完全完成,但可能高达 80-90%),如果进程本身提前完成,则提前完成,如果定时循环在进程之前完成,则只需等待接近完全完成状态。但我不建议这样做。我个人觉得这种进度指示很烦人,因为它暗示呈现的信息实际上并不存在。