Получить перенаправленный вывод процесса в строку в приложении C# - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть приложение WinForms C#, которое использует CefShar для отображения локальной веб-страницы ноутбука Jupyter. Я запускаю блокнот jupyter со следующим кодом:

   private string startJupyterNotebook()
    {
        Process consoleProcess = new Process();
        consoleProcess.StartInfo.RedirectStandardOutput = true;
        consoleProcess.StartInfo.FileName = "cmd.exe";
        consoleProcess.StartInfo.UseShellExecute = false;
        consoleProcess.StartInfo.Arguments = "/C jupyter notebook --no-browser";

        consoleProcess.Start();

        var reader = consoleProcess.StandardOutput;
        while (!reader.EndOfStream)
        {
            var nextline = reader.ReadLine();
            //search for url in output
        }

        consoleProcess.WaitForExit();

        var output = "LinkFoundInTheOutputStringOfProcess";

        return output;}

В консоли отладчика Visual Studio я вижу требуемый вывод (URL с токеном), но в приложении я не получаю строку консоли. Чего мне не хватает?

Это выход из консоли в Visual Studio, который я хочу использовать позже:

To access the notebook, open this file in a browser:
    file:///C:/Users/kuehn_c/AppData/Roaming/jupyter/runtime/nbserver-18200-open.html
Or copy and paste one of these URLs:
    http://localhost:8863/?token=9825f97d8828e44d1abe977aa087f440a162600c57fd5337
 or http://127.0.0.1:8863/?token=9825f97d8828e44d1abe977aa087f440a162600c57fd5337

Весь процесс запуска jupyter должен быть скрыт от пользователя и должен быть завершение работы, когда приложение закрывается.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020
    private readonly ChromiumWebBrowser browser;

    private Process consoleProcess = new Process();

    private string consoleText;

    void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data.Contains("http"))
        {
            string data = e.Data;
            int pos = data.IndexOf("http:");
            consoleText = data.Remove(0,pos);
        }
    }

    void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(e.Data + "\n");
    }

    private string startJupyterNotebook()
    {
        consoleProcess.EnableRaisingEvents = true;
        consoleProcess.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
        consoleProcess.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);


        consoleProcess.StartInfo.FileName = "cmd.exe";
        consoleProcess.StartInfo.Arguments = "/C jupyter notebook --no-browser";
        consoleProcess.StartInfo.RedirectStandardOutput = true;
        consoleProcess.StartInfo.RedirectStandardError = true;
        consoleProcess.StartInfo.UseShellExecute = false;
        consoleProcess.StartInfo.CreateNoWindow = false;

        consoleProcess.Start();

        consoleProcess.BeginErrorReadLine();

        var link = consoleText; //"http://localhost:8888/tree/";

        return link;
    }

    public BrowserForm()
    {
        var jupyterLink = startJupyterNotebook();

        InitializeComponent();

        Text = "CefSharp";
        WindowState = FormWindowState.Maximized;
        if (consoleLog == null)
        {
            browser = new ChromiumWebBrowser("http://localhost:8888/tree/");
        }
        else
        {
            browser = new ChromiumWebBrowser(jupyterLink);
        }

        toolStripContainer.ContentPanel.Controls.Add(browser);

        browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
        browser.LoadingStateChanged += OnLoadingStateChanged;
        browser.ConsoleMessage += OnBrowserConsoleMessage;
        browser.StatusMessage += OnBrowserStatusMessage;
        browser.TitleChanged += OnBrowserTitleChanged;
        browser.AddressChanged += OnBrowserAddressChanged;

        var version = string.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}",
           Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);

        DisplayOutput(string.Format("{0}, {1}", version, environment));
    }
0 голосов
/ 02 апреля 2020

Может быть, это потому, что C# приложение передает Аргументы как Unicode, а приложение, в которое вы отправляете аргументы Unicode, не обрабатывает аргументы Unicode.

Попробуйте это:

consoleProcess.StartInfo.Arguments = Encoding.Default.GetString(Encoding.UTF8.GetBytes("/C jupyter notebook --no-browser"));

Если это не будет работать, попробуйте создать командный файл. При вызове через пакетный файл аргументы не будут передаваться как Unicode.

Если вы попробуете пакетный файл, вот некоторый код, который может быть полезен.

    Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = @"C:\Users\test.bat"
    p.StartInfo.WorkingDirectory =  @"C:\Users\"
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.CreateNoWindow = true;
    p.Start();
    p.WaitForExit();

А затем в test.bat просто напишите это:

start "" "c:\application.exe" /C jupyter notebook --no-browser
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...