【问题标题】:C# How to Get Output from CMD (Command = "Defrag c: /U") Before Proccess Ends.C# 如何在进程结束前从 CMD 获取输出(Command = "Defrag c: /U")。
【发布时间】:2014-11-02 18:07:57
【问题描述】:

我正在从我的 c# 应用程序中调用 Defrag.exe。我想在更新时获得碎片整理过程的输出。

我希望在我的应用程序中打印此输出(红色矩形)。(当更新 11% 的进度百分比时,也应该打印它。):

我正在使用此代码:

Process selectedProc = new Process();
selectedProc.StartInfo.UseShellExecute = false;
selectedProc.StartInfo.RedirectStandardOutput = true;
selectedProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
selectedProc.StartInfo.CreateNoWindow = true;

selectedProc.OutputDataReceived += (sender, e) => 
{                
       Debug.WriteLine(e.Data); 
};

selectedProc.StartInfo.WorkingDirectory = System.IO.Path.GetPathRoot(Environment.SystemDirectory);
selectedProc.StartInfo.FileName = System.IO.Path.Combine(Environment.SystemDirectory, "defrag.exe");
selectedProc.StartInfo.Arguments = "C: /U";
selectedProc.Start();
selectedProc.BeginOutputReadLine();

一段时间后,我将使用此代码关闭进程:

selectedProc.Kill();

在 process.Start() 和 process.Kill() 之间,我没有在 Visual Studio 的调试部分看到任何输出。即使在碎片整理过程结束后也没有。问题出在哪里?

【问题讨论】:

  • 它可能在错误流中...
  • 不,它也不会在错误流上输出任何内容。
  • 太糟糕了。为什么不使用 WMI 提供程序呢? stackoverflow.com/a/11873832/578411
  • 不明白该答案是否与我的问题有关。 DefragAnalysis 分析卷并判断是否需要进行碎片整理。我想在对驱动器进行碎片整理时跟踪进度。(如屏幕截图所示)
  • 它调用碎片整理,碎片整理分析是输出参数...

标签: c# cmd output


【解决方案1】:

您需要以管理员身份运行 cmd 并传递参数以运行碎片整理

namespace System.IO.Defrag
{
    using System.Diagnostics;
    using System.Text.RegularExpressions;

    public class Defrag
    {
        private Process ownprocess;
public void Stop()
        {
            ownprocess?.Kill();
        }
        private IDictionary<Operations, string> vOperations = new Dictionary<Operations, string>()
        {
            {Operations.Analyze, "/A "},{ Operations.BootOptimize,"/B "},{ Operations.Defrag ,"/D "},
            {Operations.Optimize ,"/O "},{ Operations.FreespaceConsolidate,"/X "},{ Operations.PrintProgress,"/U "},
            {Operations.Retrim,"/L " },{ Operations.SlabConsolidate ,"/K "},{ Operations.TierOptimize,"/G "},
            {Operations.TrackProgress ,"/T "},{ Operations.Verbose,"/V"}
        };
        private IDictionary<Options, string> vOptions = new Dictionary<Options, string>()
        {
            {Options.MultiThread , "/M" },{ Options.MaxRuntime, "I"},{ Options.NormalPriority , "/H"},
            { Options.None,""}
        };
        public enum Options
        {
            NormalPriority,
            MaxRuntime,
            MultiThread,
            None
        }
        public enum Operations
        {
            Analyze,
            BootOptimize,
            Defrag,
            TierOptimize,
            SlabConsolidate,
            Retrim,
            Optimize,
            TrackProgress,
            PrintProgress,
            Verbose,
            FreespaceConsolidate
        }
        private string English = "437";
        public event DataReceivedEventHandler OutputData;

        public T GetValue<T>(string data)
        {
            object o = new object();
            T a = (T)o;
            if (a is string)
            {
                Regex he = new Regex(": (.*?)% ");
                var j = he.Match(data);
                o = j.Groups[1].Value;
                a = (T)o;
            }
            else if (a is int)
            {
                Regex he = new Regex(": (.*?)% ");
                var j = he.Match(data);
                o = Convert.ToInt32(j.Groups[1].Value);
                a = (T)o;
            }
            else if (a is double)
            {
                Regex he = new Regex(": (.*?)% ");
                var j = he.Match(data);
                o = Convert.ToDouble(j.Groups[1].Value);
                a = (T)o;
            }
            else
            {
                MessageBox.Show("This format is not supported.",$"Error 0x{Encoding.UTF8.GetBytes(a.GetType().Name).Length}",MessageBoxButton.OK,MessageBoxImage.Error);
            }
            return a;
        }
        private void cmd(string arg)
        {

            Process process = new Process();
            process.StartInfo = new ProcessStartInfo("cmd",$"/c start \"\" chcp {English} && start \"\" {arg}");
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            if (OutputData != null)
            {
                process.StartInfo.RedirectStandardOutput = true;
                process.OutputDataReceived += OutputData;
                ownprocess = process;
                process.Start();
                process.BeginOutputReadLine();
            }else
            {
                ownprocess = process;
                process.Start();

            }
        }
        public async void Start(string Volumes = "C:", Operations dOparations  = Operations.Defrag, Options options = Options.None)
        {
            await Task.Factory.StartNew(() => 
            {
                cmd($"defrag {Volumes} {vOperations[dOparations]}{vOptions[options]}");

            });
        }

    }

}

【讨论】:

  • 如果你只是运行碎片整理,你将看不到输出
  • 鉴于代码示例有多长,调出相关功能会很有用。
猜你喜欢
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
  • 2021-08-08
  • 2014-12-14
  • 1970-01-01
  • 2020-06-26
相关资源
最近更新 更多