Hello everyone, I'm rather new at C# and programming in general, I have some experience with Java, PERL, and Python but I wouldn't consider myself an expert on any of them. I'm using C# because it is very similar to Java and it seems to be even easier to make GUIs with it.

That being said I'm currently stuck with my program. This is my third C# program and so far I've been able to iron out most of the bugs except for one. I'm getting the runtime error: System.NullReferenceException: Object reference not set to an instance of an object. I've tried everything I know of to try and fix it and I've looked up the error and I believe that I basically understand it but I still can't fix it. If you could lend any help it would be very much appreciated.

Here is the code that I believe to be the most relevant to the problem but it is not all of my code. If you would like to see all my code I would be happy to post it as well.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Media;

namespace MKV2MP4
{
    public partial class MKV2MP4 : Form
    {
        
        public string mkvLoc;
        public string vidLoc;
        public string tcLoc;
        public string audioLoc;
        public string chapLoc;
        public string outLoc;
        public string currentDirectory = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location);

        public MKV2MP4()
        {
            InitializeComponent();
        }
//Method that calls method that gives error
       private void button1_Click(object sender, EventArgs e)
        {
            string fileName;
            string filePath;

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Select MKV Source";
            ofd.CheckFileExists = true;
            ofd.CheckPathExists = true;
            ofd.Filter = "MKV File (*.mkv)|*.mkv|" + "All files (*.*)|*.*";
            ofd.AddExtension = true;
            ofd.DefaultExt = "mkv";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                fileName = System.IO.Path.GetFileName(ofd.FileName);
                filePath = System.IO.Path.GetDirectoryName(ofd.FileName);

                mkvLoc = System.IO.Path.Combine(filePath, fileName);

                readStreams(mkvLoc); //Actual call to method that gives error
                mkvLocBox.Text = mkvLoc;
                
            }

            else
            {
                MessageBox.Show("Warning: No video file selected");
            }

        }
//Method that gives error
private void readStreams(string mkvLoc) //Gives error: Object reference not set to an instance of an object
        {
            try
            {
                Process read = new Process();
                read.StartInfo.WorkingDirectory = currentDirectory + @"\MKVtoolnix\";
                read.StartInfo.FileName = "mkvmerge.exe";
                read.StartInfo.RedirectStandardOutput = true;
                read.StartInfo.RedirectStandardInput = true;
                read.StartInfo.UseShellExecute = false;
                read.StartInfo.CreateNoWindow = true;
                read.StartInfo.Arguments = String.Format("-i \"{0}\"", mkvLoc);
                read.Start();

                StreamReader myStreamReader = read.StandardOutput;
                string[] streams = new string[1000];
                string isMkvTest = myStreamReader.ReadLine();
                string isMkv = isMkvTest.Substring(isMkvTest.LastIndexOf(':'));

                if (isMkv == ": Matroska")
                {
                    for (int i = 1; i < 1000; i++)
                    {
                        string s = myStreamReader.ReadLine();

                        if (s.Trim().Length == 0)
                            break;

                        streams[i] = s;

                    }

                    read.Close();
                    //Send streams[] to streamList
                    streamList.Items.AddRange(streams);

                }

                else
                {
                    read.Close();
                    MessageBox.Show("File is not a valid Matroska file.");
                }

            }

           catch(Exception e)
            {
                MessageBox.Show("Error: " + e.StackTrace);
            }

        }
    }
}

Again thank you for any help you can give me. I am not a software developer it is just a hobby to help with my own computing needs, and therefore I don't have advanced knowledge in programming. Also if you could look at my for loop for reading another programs output and tell me if there is a better way to do it.

Have you used debug to trace to the actual line that crashes ?
I would venture to guess that it is at the line:
string isMkv = isMkvTest.Substring(isMkvTest.LastIndexOf(':'));

There is no guarantee that isMkvTest is instantiated.
Just because you are asking it to readline, does not mean that there is a non null value returned. Anyway, best bet is to set a break point at the top of the readStreams method, and step to the problem... Something is null that should not be.

// Jerry

The only debugging I have done or know how to do in C# is with StackTrace and it says that the error is at line 64. Is there something else that I should be doing?

Also I tried changing lines 83 to 94 to this:

if (isMkvTest.Trim().Length != 0)
                {
                    string isMkv = isMkvTest.Substring(isMkvTest.LastIndexOf(':'));

                    if (isMkv == ": Matroska")
                    {
                        for (int i = 1; i < 1000; i++)
                        {
                            string s = myStreamReader.ReadLine();

                            if (s.Trim().Length == 0)
                                break;

                            streams[i] = s;

                        }

But I still get the same error message. Is that the same problem as before with using isMkvTest.Trim().Length? And if so how can I recode it so that it works?

And I can't use a break because the first line of the other programs output is what type of file it is so I only want to check it once. Any more help? Thanks!

I am thinking that isMkvTest is null.
You can test for that by changing:

if (isMkvTest.Trim().Length != 0)

change to:

if( !string.IsNullOrEmpty( isMkvTest ) )

As for using the Visual Studio Debugger. Simple... Left click the margin to the left of the code you want as a break point. You should get a red ball to appear, and the text will be back-lit with red. Press the F5 key to start debugging. Next, when it gets to that line, step into it with F11, or through it with F10. You can hover the mouse of an object to get its value, and you will see lots of other options once you start using the debugging tools.
If you do not have Visual Studio, then get the free express version from MSDN, and use it to debug your program.

// Jerry

Well I figured out that the problem is most likely caused because the external program just "flashes" onscreen for less than a second which means that when I try to read from it there is nothing to read from. I've tested the external program from the command line and it works just fine but when it is called by my program it just "flashes" for lack of a better term. So is there a way to fix this? Like a way to keep the console up until the method finishes? I have a Close() but it doesn't seem to be working because it closes without doing anything.

This is the code I am currently using to test it: (with the commented out code)

Process read = new Process();
                read.StartInfo.WorkingDirectory = currentDirectory + @"\MKVtoolnix\";
                read.StartInfo.FileName = "mkvmerge.exe";
             //   read.StartInfo.RedirectStandardOutput = true;
             //   read.StartInfo.RedirectStandardInput = true;
             //   read.StartInfo.UseShellExecute = false;
             //   read.StartInfo.CreateNoWindow = true;
                read.StartInfo.Arguments = String.Format("-i \"{0}\"", mkvLoc);
                read.Start();
             //   read.WaitForExit();

            //    StreamReader myStreamReader = read.StandardOutput;
                string[] streams = new string[1000];
                string isMkvTest = Console.ReadLine();
                MessageBox.Show(isMkvTest);
                read.Close();

I had to change it to Console.ReadLine() because as you said it was causing the problem but it was actually happening earlier in the code. (At line 80) Do you have any idea of what I should do?

I figured out that I needed to use ReadToEnd() to get it to work properly but now it seems to be working just fine. Thanks for your help.

Glad you figured it out, and I apologize for not telling you about that. I was sidetracked with another DaniWeb'er and forgot to get that information to you.
Again, Sorry
//Jerry

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.