如何制作 C# 控制台应用程序 .exe 以打开保存对话框以保存应用程序生成的文件?

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

我的代码:

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

当我 运行 .exe 时,显然我无法将新文件 MOCK_DATA_SORTED.json 保存到我想要的地方。

求助!

真的想要在控制台应用程序中显示“另存为”对话框吗?如果是这样,请查看问题的评论,了解如何从您的控制台应用程序引用 System.Windows.Forms 程序集,并将 using 指令添加到 System.Windows.Forms 到您的 Program class .我觉得有点不对劲,如果您想要一个打开对话框的应用程序,那么创建 Windows Forms 或 WPF 应用程序比创建控制台应用程序更容易。但是我要评判谁呢?

但是如果您想要一个控制台应用程序,并且您希望 运行 使用该应用程序的人在他们 运行 应用程序时决定将输出文件保存在何处,我' d 建议两种方法。

命令行参数

首先, 扩展关于使用命令行参数的内容。

在方法签名中

public static void Main(string[] args)

该参数 args 表示传递给您的应用程序的所有命令行参数。例如,假设您的应用程序可执行文件名为 MyApp.exe 并且您从命令行调用它:

MyApp first second "third fourth fifth" sixth

那么args会是一个数组,有4个元素,每个元素都是一个字符串,有如下值

first
second
third fourth fifth
sixth

(请注意命令行中“third fourth fifth”是如何用引号括起来的,这会导致将 3 个单独的单词作为数组的单个元素而不是 3 个不同的元素传递,如果您的参数包含空格。)

因此,对于您的用例,您希望用户在 运行 时指定目标路径,请考虑此程序:

namespace Whosebug68880709ConsoleAppArgs
{
    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);
        }
    }
}

假设您的应用程序仍然编译为名为 MyApp.exe 的可执行文件,您可以 运行 从命令提示符中像这样

MyApp C:\SomewhereIWantToSaveTheFile

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

正在接受来自控制台的输入

如果您不希望您的用户必须处理命令提示符并导航到部署 .exe 的位置,并且您希望他们能够通过从内部双击应用程序来启动应用程序文件资源管理器,您可以改用这种方法:

namespace Whosebug68880709ConsoleAppArgs
{
    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);
        }
    }
}

此版本允许用户通过双击启动应用程序,并且在控制台中 window 它将提示他们输入应保存输出文件的文件夹的路径。

结论

我已经向您展示了两种在 运行 时将信息传递到控制台应用程序的非常常用的方法,希望您会觉得有用。如果您既是该应用程序的用户又是其开发者,那么您也应该能够运行以这些方式中的任何一种来使用它。

但是,如果应用程序的用户是其他一些人,他们坚持认为他们需要某种“另存为”对话框才能浏览到目标文件夹,那么只要您从 UI 框架,例如 Windows Forms 或 WPF,您不妨围绕该框架构建您的应用程序,而不是使其成为控制台应用程序。

控制台应用程序非常适合非交互式批处理过程,它们非常适合技术娴熟的用户社区(想想开发人员、服务器管理员等),但对于非技术用户来说却不是很好习惯于通过单击和拖放来完成所有事情。

欢迎来到 Stack Overflow 顺便说一句:-)