إعادة توجيه وحدة الإخراج إلى النص في برنامج منفصل

StackOverflow https://stackoverflow.com/questions/415620

سؤال

وأنا تطوير نماذج Windows التطبيق الذي يتطلب مني أن أتصل برنامج منفصل لتنفيذ مهمة. هذا البرنامج هو تطبيق وحدة وأنا بحاجة لإعادة توجيه الإخراج القياسي من وحدة التحكم لمربع نص في برنامجي.

وليس لدي أي مشكلة تنفيذ البرنامج من طلبي، لكنني لا أعرف كيف لإعادة توجيه الإخراج إلى طلبي. ولست بحاجة لالتقاط الانتاج في حين يتم تشغيل البرنامج باستخدام الأحداث.

لا يهدف برنامج وحدة لإيقاف تشغيل حتى يتوقف طلبي وتغيير النص باستمرار في فترات عشوائية. ما أنا يحاول القيام به هو مجرد ربط الناتج من وحدة التحكم لتحريك معالج حدث ومن ثم يمكن استخدامها لتحديث مربع نص.

وأستخدمه C # لرمز البرنامج وباستخدام .NET Framework للتنمية. التطبيق الأصلي هو ليس برنامج .NET.

وتحرير: وهنا مثال التعليمة البرمجية ما أحاول القيام به. في بلدي التطبيق النهائي، وسوف يحل محل Console.WriteLine مع رمز لتحديث مربع نص. حاولت تعيين نقطة توقف في بلدي معالج الأحداث، ولا حتى وصلت عليه.

    void Method()
    {
        var p = new Process();
        var path = @"C:\ConsoleApp.exe";

        p.StartInfo.FileName = path;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += p_OutputDataReceived;

        p.Start();
    }

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(">>> {0}", e.Data);
    }
هل كانت مفيدة؟

المحلول

وهذا يعمل بالنسبة لي:

void RunWithRedirect(string cmdPath)
{
    var proc = new Process();
    proc.StartInfo.FileName = cmdPath;

    // set up output redirection
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;    
    proc.EnableRaisingEvents = true;
    proc.StartInfo.CreateNoWindow = true;
    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;

    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    // output will be in string e.Data
}

نصائح أخرى

ويمكنك استخدام التعليمات البرمجية التالية

        MemoryStream mem = new MemoryStream(1000);
        StreamWriter writer = new StreamWriter(mem);
        Console.SetOut(writer);

        Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
        assembly.EntryPoint.Invoke(null, null);
        writer.Close();

        string s = Encoding.Default.GetString(mem.ToArray());
        mem.Close();

ولقد أضاف عدد من الأساليب المساعد ل (مشروع مفتوح المصدر) O2 منصة التي تسمح لك بسهولة النصي ل التفاعل مع عملية أخرى عن طريق وحدة الإخراج والإدخال (يرى <وأ href = "http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs" يختلط = "نوفولو"> http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs )

ومفيدة بالنسبة لك قد يكون API التي تتيح للمشاهدة من حدة الانتاج من العملية الحالية (في إطار التحكم أو المنبثقة الحالية) أيضا. نرى هذا بلوق وظيفة لمزيد من التفاصيل: <لأ href = "http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/" يختلط = "نوفولو "> http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (ويحتوي هذا بلوق أيضا تفاصيل عن كيفية تستهلك وحدة الناتج من العمليات الجديدة)

وبفضل مارك Maxham لإجابته التي توفر لي الوقت!

وأما جون لجميع الحرف تلاحظ ذلك، يجب تعيين UseShellExecute إلى false من أجل إعادة توجيه IO تيارات، وإلا فإن الدعوة Start() يلقي على InvalidOperationException.

وهنا هو بلدي تعديل التعليمات البرمجية حيث txtOut هو WPF للقراءة فقط مربع نص

void RunWithRedirect(string cmdargs)
{
    var proc = new Process()
    {
        StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };

    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;
    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
        Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top