繁体   English   中英

从C#调用Edge.js时,如何挂钩stdout和stderr?

When calling Edge.js from C#, how do you hook stdout and stderr?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

背景

我正在开发一个C#程序,它目前通过Process.Start()运行Node。 我从这个子进程捕获stdout和stderr并根据我自己的原因重定向它。 我正在寻找通过调用Edge.js替换Node.exe的调用。 为了能够做到这一点,我必须能够从Edge中运行的Javascript中可靠地捕获stdout和stderr,并将消息返回到我的C#应用​​程序中。

方法1

我将描述这种方法的完整性,以防任何人推荐:)

如果Edge进程终止,那么通过简单地声明一个msgs数组并覆盖process.stdout.writeprocess.stderr.write以及在该数组上累积消息的新函数来处理这个问题是相当容易的,然后最后只返回msgs数组。 例:

var msgs = [];
process.stdout.write = function (string) {
    msgs.push({ stream: 'o', message : string });
};
process.stderr.write = function (string) {
    msgs.push({ stream: 'e', message: string });
};

// Return to caller.
var result = { messages: msgs; ...other stuff... };
callback(null, result);

显然,这仅在Edge代码终止时有效,并且在最坏的情况下msgs可能会变大。 但是,它可能表现良好,因为只需要一次编组调用即可获得所有消息。

方法2

这有点难以解释。 我们使用从C#发送的委托来“挂钩”stdout和stderr,而不是累积消息。 在C#中,我们创建了一个将传递给Edge的对象,该对象有一个名为stdoutHook的属性:

dynamic payload = new ExpandoObject();
payload.stdoutHook = GetStdoutHook();

public Func<object, Task<object>> GetStdoutHook()
{
    Func<object, Task<object>> hook = (message) =>
    {
        TheLogger.LogMessage((message as string).Trim());
        return Task.FromResult<object>(null);
    };

    return hook;
}

我真的可以逃脱一个Action,但是Edge似乎需要Func<object, Task<object>> ,否则它不会代理该函数。 然后,在Javascript中,我们可以检测到该函数并像这样使用它:

var func = Edge.Func(@"
    return function(payload, callback) {
        if (typeof (payload.stdoutHook) === 'function') {
            process.stdout.write = payload.stdoutHook;
        }

        // do lots of stuff while stdout and stderr are hooked...
        var what = require('whatever');
        what.futz();

        // terminate.
        callback(null, result);
}");

dynamic result = func(payload).Result;

问题

Q1。 这两种技术似乎都有效,但有没有更好的方法可以做到这一点,也许是我错过了Edge内置的内容? 这两种解决方案都具有侵入性 - 它们需要一些填充码来包装要在Edge中完成的实际工作。 这不是世界末日,但如果有一种非侵入性方法会更好。

Q2。 在方法2中,我必须在这里返回任务

return Task.FromResult<object>(null);

返回已完成的“空任务”感觉不对。 但还有另一种写作方式吗?

Q3。 在挂钩stdout和stderr时,我是否需要在Javascript代码中更严格? 我注意到在double-edge.js中有这个代码,坦率地说我不确定这里发生了什么,但它比我粗略覆盖process.stdout.write更复杂:-)

// Fix #176 for GUI applications on Windows
try {
    var stdout = process.stdout;
}
catch (e) {
    // This is a Windows GUI application without stdout and stderr defined.
    // Define process.stdout and process.stderr so that all output is discarded. 
    (function () {
        var stream = require('stream');
        var NullStream = function (o) {
            stream.Writable.call(this);
            this._write = function (c, e, cb) { cb && cb(); };
        }
        require('util').inherits(NullStream, stream.Writable);
        var nullStream = new NullStream();
        process.__defineGetter__('stdout', function () { return nullStream; });
        process.__defineGetter__('stderr', function () { return nullStream; });
    })();
}
1 个回复

问题1:在从CLR调用Node时,Edge中没有任何内置功能可以自动捕获Node.js代码的stdout或stderr。 在某些时候,我想到编写Edge的扩展,这将使得跨越CLR / V8边界的编组流变得容易。 在引擎盖下,它将与您的方法2非常相似。它可以作为Edge顶部的独立模块完成。

Q2:在这种情况下,返回完成的任务非常合适。 您的函数捕获了Node.js输出,对其进行了处理,并且实际上已经“完成”了。 使用Null返回完成的任务实际上是从Action返回的道德等同物。

问题3:您指向的代码仅与Windows GUI应用程序相关,而不是控制台应用程序。 如果您正在编写控制台应用程序,那么只需覆盖write就足以在传递给Edge.js的Node.js代码级别上。 请注意, write节点的签名允许传入可选的编码参数 在方法1和方法2中,您似乎都忽略了它。特别是在方法2中,我建议将JavaScript代理包装到C#回调中,然后将参数规范化,然后再将其分配给process.stdout.write 否则,Edge.js代码可能会假定传递给write调用的encoding参数是一个遵循Edge.js调用约定的回调函数。

1 从C#调用Edge.js中的DLL错误

首先,我安装了最新的Edge Nuget软件包 。 然后,我运行基本的hello world启动示例,并在带有Visual Studio 2015的Windows 2010上遇到此错误。 当我在OS-X上执行相同的hello world代码时,出现此错误。 这是局部变量 ...

4 如何从edge.js func访问MSSQL返回数据?

这是一个普遍的JS问题,并不是特定于edge.js. 我想通过edge.js玩SQL Server访问。 基于GitHub网站的以下片段 我写了以下内容来访问我自己的数据库: 我的问题是,如何从logResult返回结果而不是仅使用该函数内的数据? 而不是现在登录到控制台的 ...

5 如何在C#中使用线程读取stdout和stderr

我正在尝试制作python解释器,并且发现了带有python代码的python解释器。 我用c#进行了编码,但没有显示输出。 这是带有python代码的python解释器。 class Console(tk.Frame): def __init__(self,parent=No ...

2019-08-18 15:54:02 0 35   c#/ python
7 使用edge.js,.Net C#模块可以调用流程中的node.js部分,即是否进行反向调用?

您可以在此处看到要从Node.js-&gt; C#开始的互操作模型。 我想知道的是,在返回之前,C#代码是否可以从C#调用进程的Node.js部分中的方法? 想像一下您是否打过电话,例如 MyDotNetApi.csx返回的位置,但保持套接字侦听器线程运行以处理HTTP请求。 ...

8 您如何在procmail中记录MDA的stdout和stderr?

我对使用fetchmail和procmail比较陌生。 我从某人那里继承了一个系统,并且试图调试为传递消息而编写的MDA。 这是一个用perl编写的程序,其中包含“打印”语句。 我想知道如何让procmail将MDA的输出(stdout)写入某个地方的日志文件。 它似乎没有转到LOGFI ...

10 我在哪里将edge.js的dll放入访问

我一直在使用edge.js从我的Node.js应用程序中调用C#函数,但是当我去执行C#代码时,我得到了例子: 找不到元数据文件'System.Collections.Generic.dll' 找不到元数据文件'System.Text.dll' ... 我的代码 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM