How to make a c# console app .exe to open a save dialog to save a file generated by the app?

763 views Asked by At

My code:

static void Main(string[] args)
        {
            string filePath = "./MOCK_DATA.json";
            List<UserModel> datas = JsonConvert.DeserializeObject<List<UserModel>>(File.ReadAllText(filePath));
            int count = datas.Count;
            for (var i = 0; i < count - 1; i++)
            {
                for (var j = 0; j < count - 1 - i; j++)
                {
                    if (String.Compare(datas[j].VIN, datas[j + 1].VIN) > 0)
                    {
                        UserModel temp = datas[j + 1];
                        datas[j + 1] = datas[j];
                        datas[j] = temp;
                    }
                }
            }
       
            File.WriteAllText("./MOCK_DATA_SORTED.json",JsonConvert.SerializeObject(datas, Formatting.Indented));   
        }

When I run the .exe, obviously I can't save the new file MOCK_DATA_SORTED.json where I want.

Help!

1

There are 1 answers

3
sbridewell On BEST ANSWER

Do you really want to display a Save As dialogue in a console application? If so, then check out the comments on the question to see how to reference the System.Windows.Forms assembly from your console application and add a using directive to System.Windows.Forms to your Program class. It feels a bit wrong to me, if you want an application which opens dialogue boxes then it's easier to create a Windows Forms or WPF application rather than a console application. But who am I to judge?

But if you want a console application, and you want the person who runs that application to decide where to save the output file at the time when they run the application, I'd suggest two approaches.

Command line arguments

First, to expand on Klaus Gutter's comment about using command line arguments.

In the method signature

public static void Main(string[] args)

That parameter args represents all the command line arguments passed to your application. For example, assuming your application executable is called MyApp.exe and you call it from the command line thus:

MyApp first second "third fourth fifth" sixth

Then args will be an array with 4 elements, each of which is a string, with the following values

first
second
third fourth fifth
sixth

(Note how "third fourth fifth" is enclosed in quotes on the command line, this causes the 3 separate words to be passed as a single element of the array rather than 3 different elements, this is useful if your arguments contain spaces.)

So, for your use case, where you want the user to specify the destination path at runtime, consider this program:

namespace StackOverflow68880709ConsoleAppArgs
{
    using System;
    using System.IO;

    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine(@"Usage: MyApp C:\Temp");
                return; // or you could throw an exception here
            }

            var destinationFolder = args[0];
            if (!Directory.Exists(destinationFolder))
            {
                Console.WriteLine("Destination folder " + destinationFolder + " doesn't exist");
                return; // or you could throw an exception here
            }

            var data = "stuff to write to the file"; // put your logic to create the data here

            var destinationPath = Path.Combine(destinationFolder, "MOCK_DATA_SORTED.json");
            File.WriteAllText(destinationPath, data);
        }
    }
}

Assuming your application still compiles to an executable called MyApp.exe, you can run this from the command prompt like this

MyApp C:\SomewhereIWantToSaveTheFile

or

MyApp "C:\Some folder with spaces in the name"

Accepting input from the console

If you don't want your users to have to deal with command prompts and having to navigate to where the .exe is deployed, and you want them to be able to launch the application by double-clicking it from within File Explorer, you could use this approach instead:

namespace StackOverflow68880709ConsoleAppArgs
{
    using System;
    using System.IO;

    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Please enter destination folder");
            var destinationFolder = Console.ReadLine();

            if (!Directory.Exists(destinationFolder))
            {
                Console.WriteLine("Destination folder " + destinationFolder + " doesn't exist");
                return; // or you could loop back and prompt the user again
            }

            var data = "stuff to write to the file"; // put your logic to create the data here

            var destinationPath = Path.Combine(destinationFolder, "MOCK_DATA_SORTED.json");
            File.WriteAllText(destinationPath, data);
        }
    }
}

This version allows the user to launch the application by double-clicking on it, and within the console window it will prompt them to enter the path to the folder where the output file should be saved.

Conclusion

I've shown you two very common ways of passing information into a console application at runtime, which I hope you'll find useful. If you're the user of this application as well as its developer, then you should also be more than capable of running it in either of these ways.

However, if the application's users are some other group of people who insist that they need some kind of Save As dialogue to browse to the destination folder, as soon as you bring that dialogue in from from a UI framework such as Windows Forms or WPF, you might as well build your application around that framework rather than making it a console application.

Console applications are great for non-interactive batch processes, and they work pretty well for user communities who are highly technically skilled (think developers, server administrators etc), but they're not great for non-technical users who are used to doing everything by clicking and drag-dropping.

Welcome to Stack Overflow BTW :-)