3

简要总结

我正在为 C# 中的 NASM 开发创建一个轻量级 IDE(我知道有点讽刺)。有点像记事本++,但更简单,但具有使其不仅仅是源代码编辑器的功能。因为 Notepad++ 实际上只是一个花哨的源代码编辑器。我已经实现了项目创建等功能(使用类似于 Visual Studio 组织项目的项目格式)。项目扩展名 .nasmproj。我也在将它托管在一个开源的地方(Codeplex)。虽然程序远未完成,但如果没有适当的保护和设备,绝对不能在生产环境中使用。此外,我现在独自工作,更像是一个业余项目,因为我刚刚完成了上一个夏季期末考试微积分 I。

问题

现在我面临一个问题,我可以构建项目,但没有来自 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 中的输出应该是这样的):

假设显示的输出

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

调试器信息

4

1 回答 1

2

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

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

以下是输出的格式如下:

带输出的 IDE

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

于 2012-06-22T18:34:05.130 回答