新手,如何启动此功能

时间:2015-03-19 23:38:11

标签: c# function calling-convention

对不起这个愚蠢的问题,我是c#的新手,而且我的Vb多年未受影响..

基于这篇文章:Process Start

这里是代码:

 public static int Run(Action<string> output, TextReader input, string exe, params string[] args)
  {
     if (String.IsNullOrEmpty(exe))
        throw new FileNotFoundException();
     if (output == null)
        throw new ArgumentNullException("output");

     ProcessStartInfo psi = new ProcessStartInfo();
     psi.UseShellExecute = false;
     psi.RedirectStandardError = true;
     psi.RedirectStandardOutput = true;
     psi.RedirectStandardInput = true;
     psi.WindowStyle = ProcessWindowStyle.Hidden;
     psi.CreateNoWindow = true;
     psi.ErrorDialog = false;
     psi.WorkingDirectory = Environment.CurrentDirectory;
     psi.FileName = FindExePath(exe); //see http://csharptest.net/?p=526
     psi.Arguments = EscapeArguments(args); // see http://csharptest.net/?p=529

     using (Process process = Process.Start(psi))
     using (ManualResetEvent mreOut = new ManualResetEvent(false),
     mreErr = new ManualResetEvent(false))
     {
        process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
        process.BeginOutputReadLine();
        process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); };
        process.BeginErrorReadLine();

        string line;
        while (input != null && null != (line = input.ReadLine()))
           process.StandardInput.WriteLine(line);

        process.StandardInput.Close();
        process.WaitForExit();

        mreOut.WaitOne();
        mreErr.WaitOne();
        return process.ExitCode;
     }
  }

......我怎么称呼这个功能?

我用这个修改了函数:

public static int Run(Action<string> output, TextReader input, string exe, string args)

...因为我已经知道了exe路径,我想直接将args作为直接字符串传递,但我不知道如何使用输出和输入变量。

顺便说一句,我理解功能,但如何调用它? 澄清请帮我填一下?这里:

Run(???, ???, "console.exe", " -someargs");

一个代码示例将非常感激...再次抱歉我的愚蠢问题和我糟糕的英语语言。

此致

3 个答案:

答案 0 :(得分:1)

从我发现的,

Action<String> 

可以找到 - What is Action<string>?

Action<String> print = (x) => Console.WriteLine(x);

List<String> names = new List<String> { "pierre", "paul", "jacques" };
names.ForEach(print);

至于TextReader,看起来你需要阅读一个文件,你可以找到该怎么做 - http://www.dotnetperls.com/textreader

using (TextReader reader = File.OpenText(@"C:\perl.txt"))
{
    public static int Run(print, reader, "console.exe", " -someargs")
}

我无法告诉你填充对象的属性是什么,因为我不知道你想要实现什么,但缺少的参数基本上是两个对象,你需要创建它们并传递它们我提供的链接应该为您提供有关如何创建它们的足够信息。

答案 1 :(得分:0)

假设您对exe产生的输出不感兴趣,并且您不想在流程中输入任何数据,您可以像这样调用函数:

Run((outMsg) => {}, null, "console.exe", " -someargs");

<强>解释

第一个参数是Action<string>,这意味着它需要一个带有一个字符串参数的函数。从标准输出或标准错误的进程接收的每个数据都将传递给此函数。 在上面的例子中,我刚刚插入了一个lambda表达式,它接受一个参数并且什么都不做。

第二个参数是一个TextReader实例,它似乎是可选的,因此可以在不需要时传递为null。 如果设置,则将TextReader的内容写入进程的标准输入。

答案 2 :(得分:0)

嗯,我找到了解决方案,而不是我在这里发布给其他人(希望我能其他人请删除它..)

获得输出的方法非常简单:

基于此代码:

&#13;
&#13;
        public static int Run(Action<string> output, string exe, string args)
        {
            if (String.IsNullOrEmpty(exe))
                throw new FileNotFoundException();
            if (output == null)
                throw new ArgumentNullException("output");

            ProcessStartInfo psi = new ProcessStartInfo();
            psi.UseShellExecute = false;
            psi.RedirectStandardError = true;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.CreateNoWindow = true;
            psi.ErrorDialog = false;
            psi.WorkingDirectory = Environment.CurrentDirectory;
            psi.FileName = FindExePath("cdrecord.exe"); //see http://csharptest.net/?p=526
            psi.Arguments = " -scanbus -v"; // see http://csharptest.net/?p=529

            using (Process process = Process.Start(psi))
            using (ManualResetEvent mreOut = new ManualResetEvent(false),
            mreErr = new ManualResetEvent(false))
            {
                process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
                process.BeginOutputReadLine();
                
                process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); };
                process.BeginErrorReadLine();

                output = s => ShowWindowsMessage(s);

                process.StandardInput.Close();
                process.WaitForExit();

                mreOut.WaitOne();
                mreErr.WaitOne();

                
                return process.ExitCode;
            }
        }

        public static string FindExePath(string exe)
        {
            exe = Environment.ExpandEnvironmentVariables(exe);
            if (!File.Exists(exe))
            {
                if (Path.GetDirectoryName(exe) == String.Empty)
                {
                    foreach (string test in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(';'))
                    {
                        string path = test.Trim();
                        if (!String.IsNullOrEmpty(path) && File.Exists(path = Path.Combine(path, exe)))
                            return Path.GetFullPath(path);
                    }
                }
                throw new FileNotFoundException(new FileNotFoundException().Message, exe);
            }
            return Path.GetFullPath(exe);
        }
    private static void ShowWindowsMessage(string message)
    {
        MessageBox.Show(message);
    }
&#13;
&#13;
&#13;

哪个能够启动进程并读取其输出,可以使用以下命令调用它:

&#13;
&#13;
        private void lbl_devices_Click(object sender, EventArgs e)
        {
           int h;
           h = Run((output) => { }, "cdrecord.exe", "-scanbus -v");

        }
&#13;
&#13;
&#13;

我使用Action添加的代码是:

output = s => ShowWindowsMessage(s);

希望这能帮助像Sythnet P和Gargo这样的其他人帮助我,非常感谢!咂嘴