Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect output from the NASM command line assembler in C#

Tags:

c#

ide

nasm

Brief Summary

I am creating a lightweight IDE for NASM development in C# (I know kind of an irony). Kinda of like Notepad++ but simpler but with features that make it more than source editor. Since Notepad++ is really just a fancy source editor. I have already implemented features like Project creation (using a project format similar to how Visual Studio organizes projects). Project extension .nasmproj. I am also in the works of hosting it in an open-source place (Codeplex). Although the program is far from finish, and definitely cannot be used in a production environment without proper protection and equipment. In addition, I am working alone with it at this moment, more like a spare time project since I just finished my last Summer final taking Calculus I.

Problem

Right now I am facing a problem, I can build the project but no output from NASM is being fed into the IDE. I have succesfully built a project, and I was able to produce object files. I even tried producing a syntax error to see if I finally see something come up but none and I check the bin folder of the test project I created and I see no object file creating. So definitely NASM is doing its magic. Is it because NASM doesn't want me to see its output. Is there a solution? Any advice would be great. Here is the code which I think is giving Trouble.

Things to Note

  • I have already checked if events have been invoked. An yes they have but they return empty strings
  • I have also checked error data and same effect.

Code

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

                    }

Edits

  • I have tried doing synchronously instead of asynchronously but still the same result (and empty string "" is returned) actually by debugging the stream is already at the end. So looks like nothing has been written into the stream.

This is what I tried:

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

And another interesting thing I have tried was I copied the arguments from the debugger and pasted it in the command line shell and I can see NASM compiling and giving the error that I wanted to see all along. So definitely not a NASM problem. Could it be a problem with my code or the .Net framework.

Here is a nice snapshot of the shell window (although not technically proof; this is what the output should look like in my IDE):

Output that is suppose to show up

Alan made a very good point, check the sub processes or threads. Is sub process and thread synonymous? But here is the problem. Almost all the properties except a select few and output/error streams are throwing an invalid operation. Here is the debugger information as an image (I wish Visual Studio would allow you to copy the entire information in click):

Debugger Information

like image 843
Daniel Lopez Avatar asked Dec 31 '25 05:12

Daniel Lopez


1 Answers

Okay I finally was able to do it. I just found this control that redirect output from a process and I just looked at the source code of it and got what I needed to do. Here is the the modified code:

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

Here is how the output is formatted like:

The IDE With Output

I also wanted to thank Alan for helping me debug my code, although he didn't physically had my code. But he really was helpful and I thank him for it.

like image 164
Daniel Lopez Avatar answered Jan 02 '26 19:01

Daniel Lopez