0

I'm very new to C# ; does someone know how to write ALL output lines to a .txt file without starting new process?

This code writes only the last record:

class Program
{
    static void Main(string[] args)
    {
        WezKomponent("Win32_DiskDrive", "Model");

        Console.ReadKey();
    }

    private static void WezKomponent(string ass, string sax)
    {
        ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass);

        foreach (ManagementObject pie in wez.Get())
        {
            Console.WriteLine(Convert.ToString(pie[sax]));

            StreamWriter SW = new StreamWriter(@"HDD.txt");
            SW.WriteLine(Convert.ToString(pie[sax]));
            SW.Close();
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Korab
  • 3
  • 3
  • Open the StreamWriter before the loop and close it afterwards. – Matthew Watson Aug 31 '18 at 10:46
  • Make your `StreamWriter` outside of the loop, only call `WriteLine` inside the loop and close the stream writer after the loop. – DavidG Aug 31 '18 at 10:46
  • Hi. Actually, it writes *all* the records, but since you open the file inside the loop you overwrite the file every time. Instead, move the `new StreamWriter` line above the `foreach` line, and `sw.Close` down outside of it and you should be good to go. – Lasse V. Karlsen Aug 31 '18 at 10:46
  • In this context `File.WriteAllText("HDD.txt", string.Join(Environment.NewLine, wez.Get()));` might be even easier – NotFound Aug 31 '18 at 10:51
  • im soo pathetic i do this several times but Never before loop shame on me – Korab Aug 31 '18 at 10:58
  • You could also replace the loop with this: `File.WriteAllLines("HDD.txt",wez.Get().Cast().Select(pie => pie[sax]));` – Tim Schmelter Aug 31 '18 at 11:05
  • https://stackoverflow.com/questions/19280555/what-is-the-best-way-to-store-data-in-c-sharp-application – Drag and Drop Aug 31 '18 at 11:06

3 Answers3

0

Actually, it does indeed write all the records to the file, the problem is that you overwrite the file each time, and thus what you observe is that only the last record is kept.

There are two solutions to this:

  1. Open the file before the loop, write all the records, then close the file
  2. Open the file inside the loop, but do so in a manner that will append new content

In general it's easier to get the first one right, so here's how to do it that way:

  1. Move the opening of the stream up and out of the loop
  2. Move the closing of the stream down and out of the loop

In essence you take these lines of code:

private static void WezKomponent(string ass, string sax)
{
    ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass);
    foreach (ManagementObject pie in wez.Get())
    {
        Console.WriteLine(Convert.ToString(pie[sax]));

        StreamWriter SW = new StreamWriter(@"HDD.txt");
        SW.WriteLine(Convert.ToString(pie[sax]));
        SW.Close();
    }
}

And change them to this:

private static void WezKomponent(string ass, string sax)
{
    ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass);

    StreamWriter SW = new StreamWriter(@"HDD.txt");
    foreach (ManagementObject pie in wez.Get())
    {
        Console.WriteLine(Convert.ToString(pie[sax]));

        SW.WriteLine(Convert.ToString(pie[sax]));
    }
    SW.Close();
}

Additionally, to be more failsafe in case of errors, it is better using this syntax:

using (... = new SomethingThatImplementsIDisposable(...))
{
}

than this:

... = new SomethingThatImplementsIDisposable(...);
...
...Close(); // or .Dispose();

So here's a better version of your method:

private static void WezKomponent(string ass, string sax)
{
    using (ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass))
    using (StreamWriter SW = new StreamWriter(@"HDD.txt"))
    {
        foreach (ManagementObject pie in wez.Get())
        {
            Console.WriteLine(Convert.ToString(pie[sax]));

            SW.WriteLine(Convert.ToString(pie[sax]));
        }
    }
}

The reason why this is better is because of the chance of exceptions in your code. If that happens, SW.Close(); will not be executed which means that you leave the stream and the file open, at least longer than intended. With a using clause like this, if an exception happens inside, the Dispose method on these objects will be called, closing the file, and in this case the ManagementObjectSearcher object as well.


So is there any way to improve your code even further? Yes, but only if you either know this other syntax I'm about to show, or willing to learn. Since you said you were new to C# you might not know it, and you might want to get comfortable with your existing code before making it even more complex from your point of view.

There's several ways to write to text files, StreamWriter is one of them, File.WriteAllLines is another but this expects the content to write to be provided as a collection of strings that will be written as a series of lines to the file.

So how can we get from your ManagementObjectSearcher object to a list of strings?

Through a set of syntax and .NET classes collectively known as "LINQ" or "Language INtegrated Query".

Here's a shorter version of your method:

private static void WezKomponent(string ass, string sax)
{
    using (ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass))
    {
        File.WriteAllLines(@"HDD.txt", wez
            .Get()
            .Select(pie => ConvertToString(pie[sax])));
    }
}

This can even be shortened down to just put more on each line and removing some unnecessary braces, and using var when the exact type can easily be discerned from the surrounding code:

private static void WezKomponent(string ass, string sax)
{
    using (var wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass))
        File.WriteAllLines(@"HDD.txt", wez.Get().Select(pie => ConvertToString(pie[sax])));
}
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
0
class Program
{
    static void Main(string[] args)
    {

        WezKomponent("Win32_DiskDrive", "Model");

        Console.ReadKey();

    }
    private static void WezKomponent(string ass, string sax)
    {
        ManagementObjectSearcher wez = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + ass);

        StreamWriter SW = new StreamWriter(@"HDD.txt");
        foreach (ManagementObject pie in wez.Get())





        {

            Console.WriteLine(Convert.ToString(pie[sax]));

            SW.WriteLine(Convert.ToString(pie[sax]));



        }
        SW.Close();
    }
Korab
  • 3
  • 3
0

Try initializing StreamWriter in a different manner.

StreamWriter SW = new StreamWriter(@"HDD.txt", append: true);

Note append: true in the constructor call.

Dmitry Korolev
  • 675
  • 4
  • 20