C# 如何在C中重定向NASM命令行汇编程序的输出 小结

C# 如何在C中重定向NASM命令行汇编程序的输出 小结,c#,ide,nasm,C#,Ide,Nasm,我正在用C为NASM开发创建一个轻量级IDE,我知道这有点讽刺。有点像记事本+,但更简单,但其功能比源代码编辑器更强大。因为Notepad++实际上只是一个花哨的源代码编辑器。我已经使用类似于VisualStudio组织项目的项目格式实现了类似于项目创建的功能。项目扩展。我也在一个开源的地方Codeplex托管它。虽然该程序还远未完成,而且如果没有适当的保护和设备,肯定无法在生产环境中使用。除此之外,我现在一个人在做这个项目,更像是一个业余项目,因为我刚刚完成了去年夏天的微积分I期末考试 问题

我正在用C为NASM开发创建一个轻量级IDE,我知道这有点讽刺。有点像记事本+,但更简单,但其功能比源代码编辑器更强大。因为Notepad++实际上只是一个花哨的源代码编辑器。我已经使用类似于VisualStudio组织项目的项目格式实现了类似于项目创建的功能。项目扩展。我也在一个开源的地方Codeplex托管它。虽然该程序还远未完成,而且如果没有适当的保护和设备,肯定无法在生产环境中使用。除此之外,我现在一个人在做这个项目,更像是一个业余项目,因为我刚刚完成了去年夏天的微积分I期末考试

问题 现在我面临一个问题,我可以构建这个项目,但是没有来自NASM的输出被输入IDE。我成功地构建了一个项目,并且能够生成对象文件。我甚至试着产生一个语法错误,看看我是否最终看到了一些东西,但没有,我检查了我创建的测试项目的bin文件夹,没有看到创建对象文件。所以NASM肯定在发挥它的魔力。是因为NASM不想让我看到它的输出。有解决办法吗?任何建议都很好。这是我认为给你带来麻烦的代码

注意事项 我已经检查了是否调用了事件。有,但返回空字符串 我还检查了错误数据和相同的效果。 密码 编辑 我已经尝试过同步而不是异步,但仍然是相同的结果,并且通过调试返回空字符串,实际上流已经结束了。看起来没有任何东西被写入流中。 这就是我所尝试的:

            string readToEnd = nasmP.StandardOutput.ReadToEnd();
            nasmP.WaitForExit();
            Console.WriteLine(readToEnd);
我尝试过的另一件有趣的事情是,我从调试器复制了参数,并将其粘贴到命令行shell中,我可以看到NASM编译并给出我一直希望看到的错误。所以肯定不是NASM的问题。这可能是我的代码或.Net框架的问题

这是shell窗口的一个很好的快照,尽管在技术上没有证据;在我的IDE中,输出应该是这样的:

Alan提出了一个非常好的观点,检查子进程或线程。子进程和线程是同义的吗?但问题是。除了少数选择和输出/错误流之外,几乎所有属性都抛出了无效操作。以下是调试器信息,我希望Visual Studio允许您在单击中复制整个信息:


好吧,我终于做到了。我刚刚发现了这个重定向过程的输出,我只是查看了它的源代码,得到了我需要做的事情。以下是修改后的代码:

public static bool Build(string command, out StringBuilder buildOutput)
        {
            try
            {
                buildOutput = new StringBuilder();
                ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
                startInfo.Arguments = "/C " + " nasm " + command;
                startInfo.RedirectStandardError = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                Process p = Process.Start(startInfo);
                string output = p.StandardOutput.ReadToEnd();
                string error = p.StandardError.ReadToEnd();
                p.WaitForExit();
                if (output.Length != 0)
                    buildOutput.Append(output);
                else if (error.Length != 0)
                    buildOutput.Append(error);
                else
                    buildOutput.Append("\n");
                return true;
            }
            catch
            {
                buildOutput = null;
                return false;
            }
        }
以下是输出的格式:


我还想感谢Alan帮助我调试代码,尽管他实际上没有我的代码。但他真的很有帮助,我为此感谢他。

Daniel,为了排除故障,您可以尝试同步替代方案,看看问题是否来自于此。代替BeginOutputReadLine,您可以执行类似字符串输出=nasmP.StandardOutput.ReadToEnd;nasmP.WaitForExit;Console.WriteLineoutput;。这是否显示任何消息?@Alan同样的结果,我认为这不是异步或同步的问题。但是感谢您提供的故障排除提示。也许NASM不允许我接收输出。也许我需要NASM开发者的意见?但我不知道,因为它在技术上应该是可行的。我明白了。接下来我要检查的是NASM是否启动了一个子进程进行编译,而实际上是子进程在独立控制台上生成输出,而不是父进程。这就解释了为什么输出流没有被写入。@Alan好的,这是有道理的,我从来没有这样想过,好的!很好…@Alan从调试器的外观来看,NASM进程没有任何线程。此外,进程中的每个属性都会引发异常。从调试器的外观来看。我将发布调试器输出的图像。好消息,欢迎您:因此,可能是读取到了重定向错误通道的末尾,这造成了差异。另外,在参数就位的情况下,输入重定向确实是不必要的。
            string readToEnd = nasmP.StandardOutput.ReadToEnd();
            nasmP.WaitForExit();
            Console.WriteLine(readToEnd);
public static bool Build(string command, out StringBuilder buildOutput)
        {
            try
            {
                buildOutput = new StringBuilder();
                ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
                startInfo.Arguments = "/C " + " nasm " + command;
                startInfo.RedirectStandardError = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                Process p = Process.Start(startInfo);
                string output = p.StandardOutput.ReadToEnd();
                string error = p.StandardError.ReadToEnd();
                p.WaitForExit();
                if (output.Length != 0)
                    buildOutput.Append(output);
                else if (error.Length != 0)
                    buildOutput.Append(error);
                else
                    buildOutput.Append("\n");
                return true;
            }
            catch
            {
                buildOutput = null;
                return false;
            }
        }