3

簡単な要約

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

また、私が試したもう 1 つの興味深い点は、デバッガーから引数をコピーして、コマンド ライン シェルに貼り付けたことです。NASM がコンパイルされ、ずっと見たかったエラーが表示されます。したがって、NASMの問題ではありません。私のコードまたは .Net フレームワークに問題がある可能性があります。

これはシェル ウィンドウの素敵なスナップショットです (ただし、技術的に証明されているわけではありません。IDE での出力は次のようになります)。

表示されるはずの出力

アランは非常に良い点を指摘しました。サブプロセスまたはスレッドを確認してください。サブプロセスとスレッドは同義ですか? しかし、ここに問題があります。一部の選択ストリームと出力/エラー ストリームを除くほとんどすべてのプロパティが、無効な操作をスローしています。これはデバッガー情報を画像として示したものです (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 に答える