简要总结
我正在为 C# 中的 NASM 开发创建一个轻量级 IDE(我知道这有点讽刺)。有点像 Notepad++,但更简单,但具有比源代码编辑器更多的功能。因为 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 允许您在单击时复制整个信息):
最佳答案
好吧,我终于能够做到了。我刚找到这个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;
}
}
输出的格式如下:
我还要感谢 Alan 帮助我调试我的代码,尽管他实际上并没有我的代码。但他真的很有帮助,我为此感谢他。
关于c# - 如何在 C# 中重定向 NASM 命令行汇编程序的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11145328/