【问题标题】:Newbie, howto to start this function新手,如何启动这个功能
【发布时间】:2015-03-20 09:25:11
【问题描述】:

请对这个愚蠢的问题感到抱歉,我是 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");

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

问候

【问题讨论】:

  • 请问可以缩进吗?
  • 我没有错误,我只是不知道如何调用它,我只是编辑,请看一下,非常感谢!
  • @GuybrushThreepwood 代码仍然缺少缩进。 :-(
  • 对不起,alexander,我刚刚批准并感谢您的帮助

标签: c# function calling-convention


【解决方案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")
}

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

【讨论】:

  • 感谢这项工作,现在项目编译并运行,但我收到此错误:System.IO.FileNotFoundException 当它尝试访问您示例为“perl.txt”的文件时,我认为是管理员权限。 .. 有办法将它指向一个文本变量而不是文件?
  • 那可能是因为你没有一个叫perl.txt的文件,我只是从给出的例子中拿来的,方法是试图读取一个文件,所以你要么需要给它一个文件阅读或如 Gargo 所述,传入 null
【解决方案2】:

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

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

说明

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

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

【讨论】:

  • 亲爱的 Cargo 非常感谢,我又读了一遍你的帖子,我想我现在明白了。不幸的是,我无法读取输出变量(在您的解释中是 outMsg) 我的目标是获取 console.exe 进程的输出,然后输出变量对我来说是必不可少的。您将其声明为 Lambda 并且它什么也不做,我如何声明它来存储控制台输出并将其取回?非常感谢您的耐心...
【解决方案3】:

好吧,我找到了解决方案,而不是在这里为其他人发布(希望我可以删除它..)

获取输出的方法就是这么简单:

基于此代码:

        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);
    }

它能够启动一个进程并读取它的输出,可以这样调用它:

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

        }

我添加的使用动作的代码是:

output = s => ShowWindowsMessage(s);

希望这能帮助 Sythnet P 和 Gargo 等其他人帮助我,非常感谢!!!!啪啪啪

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2020-06-02
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多