如何在C#中重定向NASM命令行汇编器的输出

时间:2012-06-21 19:24:16

标签: c# ide nasm

摘要

我正在用C#创建一个用于NASM开发的轻量级IDE(我知道有点讽刺)。有点像Notepad ++,但更简单,但具有使其不仅仅是源编辑器的功能。因为Notepad ++实际上只是一个奇特的源编辑器。我已经实现了项目创建等功能(使用类似于Visual Studio组织项目的项目格式)。项目扩展名.nasmproj。我也在一个开源的地方(Codeplex)进行托管。虽然该程序远未完成,但绝对不能在没有适当保护和设备的生产环境中使用。另外,我现在正独自一人工作,更像是一个业余时间项目,因为我刚刚完成了上一次夏季决赛,我拿了微积分。

问题

现在我遇到了一个问题,我可以构建项目,但没有来自NASM的输出被输入IDE。我成功地构建了一个项目,并且我能够生成目标文件。我甚至试图产生一个语法错误,看看我是否终于看到一些东西出现但没有,我检查我创建的测试项目的bin文件夹,我看不到创建的对象文件。所以NASM确实在做它的魔力。是因为NASM不希望我看到它的输出。有解决方案吗?任何建议都会很棒。这是我认为给麻烦的代码。

注意事项

  • 我已经检查过是否调用了事件。他们有,但他们返回空字符串
  • 我还检查了错误数据和相同的效果。

代码

    public static bool Build(string arguments,  out Process nasmP)
    {
        try
        {

            ProcessStartInfo nasm = new ProcessStartInfo("nasm", arguments);
            nasm.CreateNoWindow = true;
            nasm.RedirectStandardError = true;
            nasm.RedirectStandardInput = true;
            nasm.RedirectStandardOutput = true;

            nasm.UseShellExecute = false;                
            nasmP = new Process();
            nasmP.EnableRaisingEvents = true;
            nasmP.StartInfo = nasm;
            bool predicate = nasmP.Start();
            nasmP.BeginOutputReadLine();

            return true;
        }
        catch
        {
            nasmP = null;
            return false;
        }
    }
    //Hasn't been tested nor used
    public static bool Clean(string binPath)
    {
        if (binPath == null || !Directory.Exists(binPath))
        {
            throw new ArgumentException("Either path is null or it does not exist!");
        }
        else
        {
            try
            {
                DirectoryInfo binInfo = new DirectoryInfo(binPath);
                FileInfo[] filesInfo = binInfo.GetFiles();
                for (int index = 0; index < filesInfo.Length; index++)
                {
                    try
                    {
                        filesInfo[index].Delete();
                        filesInfo[index] = null;
                    }
                    catch
                    {
                        break;
                    }
                }
                GC.Collect();
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

                    using (BuildDialog dlg = new BuildDialog(currentSolution))
                    {
                        DialogResult result = dlg.ShowDialog();
                        dlg.onOutputRecieved += new BuildDialog.OnOutputRecievedHandler(delegate(Process _sender, string output)
                        {
                            if (result == System.Windows.Forms.DialogResult.OK)
                            {
                                outputWindow.Invoke(new InvokeDelegate(delegate(string o)
                                {
                                    Console.WriteLine("Data:" + o);
                                    outputWindow.Text = o;
                                }), output);
                            }
                        });

                    }

编辑

  • 我尝试过同步而不是异步但仍然是相同的结果(并返回空字符串“”)实际上通过调试流已经结束了。所以看起来没有任何内容被写入流中。

这就是我的尝试:

            string readToEnd = nasmP.StandardOutput.ReadToEnd();
            nasmP.WaitForExit();
            Console.WriteLine(readToEnd);

我尝试的另一个有趣的事情是我从调试器中复制了参数并将其粘贴到命令行shell中,我可以看到NASM编译并提供我一直想看的错误。所以绝对不是NASM的问题。这可能是我的代码或.Net框架的问题。

这是shell窗口的一个很好的快照(虽然不是技术证明;这是我的IDE中输出应该是这样的):

Output that is suppose to show up

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

Debugger Information

1 个答案:

答案 0 :(得分:2)

好的,我终于能够做到了。我刚刚发现这个control重定向进程的输出,我只看了它的源代码并得到了我需要做的事情。这是修改后的代码:

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

以下是输出格式如下:

The IDE With Output

我还要感谢Alan帮助我调试我的代码,尽管他没有亲自拥有我的代码。但他真的很有帮助,我感谢他。