【问题标题】:How restart the Console app?如何重启控制台应用程序?
【发布时间】:2011-08-08 01:39:03
【问题描述】:

当用户按“R”时,我需要重新启动应用程序控制台。

我有这个

Console.WriteLine(message, "Rebuild Log Files" 
    + " Press Enter to finish, or R to restar the program...");
string restar = Console.ReadLine();
if(restar.ToUpper() == "R")
{
   //here the code to restart the console...
}

谢谢

【问题讨论】:

  • 启动第二个 exe 来结束控制台程序,启动一个新实例,然后自行结束?
  • 明确一点,在代码中是怎样的?
  • “重启应用控制台”是什么意思?
  • 我认为您想重新启动程序,但您并不真正介意控制台(托管您的控制台程序的窗口)。对吗?
  • 是的,再次,从一开始,启动控制台窗口并启动进程..

标签: c# console console-application


【解决方案1】:

以这样的方式结束。

#if DEBUG
Process.Start("dotnet", Environment.GetCommandLineArgs().Prepend("run").Take(2));
#else
Process.Start(Environment.CommandLine);
#endif
Quit.ConsoleShutdown(null, null);

我确信这条特定的行:Process.Start("dotnet", Environment.GetCommandLineArgs().Prepend("run").Take(2)); 可以改进,因为乍一看它看起来有点混乱。

【讨论】:

    【解决方案2】:

    我意识到这是 7 岁,但我只是遇到了这个。我认为实际上调用可执行文件并关闭当前程序有点麻烦。如前所述,这是多虑了。我认为最干净和最模块化的方法是采用 Main 方法中的所有内容并制作一个不同的方法,假设 Run() 包含 Main 方法中的所有内容,然后调用新的 @987654324 @ 方法来自Main 方法或代码中需要重新启动程序的任何位置。

    如果Main 方法看起来像这样:

    static void Main(string[] args)
    {
        /*
        Main Method Variable declarations;
        Main Method Method calls;
        Whatever else in the Main Method;
        */
        int SomeNumber = 0;
        string SomeString = default(string);
    
        SomeMethodCall();
        //etc.
    }
    

    然后只需创建一个Run() 方法并将Main 中的所有内容放入其中,如下所示:

    public static void Run()
    {
        //Everything that was in the Main method previously
    
        /*
        Main Method Variable declarations;
        Main Method Method calls;
        Whatever else in the Main Method;
        */
        int SomeNumber = 0;
        string SomeString = default(string);
    
        SomeMethodCall();
        //etc.
    }
    

    现在 Run() 方法已创建,它包含之前 Main 方法中的所有内容,只需将您的 main 方法设为:

    static void Main(string[] args)
    {
        Run();
    }
    

    现在,无论您想在代码中的何处“重新启动”程序,只需像这样调用Run() 方法:

    if(/*whatever condition is met*/)
    {
        //do something first
    
        //then "re-start" the program by calling Run();
        Run();
    }
    

    所以这是对整个程序的简化:

    编辑:当我最初发布此内容时,我没有考虑任何可能已传递给程序的参数。为了解释这四件事,我的原始答案需要改变。

    1. 像这样声明一个全局List<string>

      public static List<string> MainMethodArgs = new List<string>();

    2. Main 方法中,将MainMethodArgs 列表的值设置为等于 通过args 传递给Main 方法的值如下:

      MainMethodArgs = args.ToList();

    3. 创建Run() 方法时,更改签名,使其期望 string[] 调用 args 以像这样传递给它:

      public static void Run(string[] args) { .... }

    4. 在程序中调用Run()方法的任何地方,传递MainMethodArgs 像这样给Run()

      Run(MainMethodArgs.ToArray());

    我更改了下面的示例以反映这些更改。

    using System;
    using System.Data;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExampleConsole
    {
        class Program
        {
            public static List<string> MainMethodArgs = new List<string>();
            static void Main(string[] args)
            {
                MainMethodArgs = args.ToList();
                Run(MainMethodArgs.ToArray());
            }
    
            public static void Run(string[] args)
            {
                Console.WriteLine("Run() is starting");
                Console.ReadLine();
                //stuff that used to be in the public method
                int MainMethodSomeNumber = 0;
                string MainMethodSomeString = default(string);
    
                SomeMethod();
                //etc.
            }
    
            public static void SomeMethod()
            {
                Console.WriteLine("Rebuild Log Files"
                + " Press Enter to finish, or R to restar the program...");
                string restar = Console.ReadLine();
                if (restar.ToUpper() == "R")
                {
                    //here the code to restart the console...
                    Run(MainMethodArgs.ToArray());
                }
            }
        }
    }
    

    实际上,程序被“重新启动”,而无需重新运行可执行文件并关闭程序的现有实例。这对我来说似乎更像“程序员”。

    享受吧。

    【讨论】:

    • “有效”,但不是真的。如果程序集已更新,则不会重新加载它们,并且不会清除静态变量和缓存。一个常见的“重启”场景是加载更新的程序集。
    【解决方案3】:

    另一种简单的方法

    //Start process, friendly name is something like MyApp.exe (from current bin directory)
    System.Diagnostics.Process.Start(System.AppDomain.CurrentDomain.FriendlyName);
    
    //Close the current process
    Environment.Exit(0);
    

    【讨论】:

      【解决方案4】:
      //here the code to restart the console...
      System.Diagnostics.Process.Start(Environment.GetCommandLineArgs()[0], Environment.GetCommandLineArgs().Length > 1 ? string.Join(" ", Environment.GetCommandLineArgs().Skip(1)) : null);
      

      【讨论】:

      • 这甚至无法编译。
      • 通过正确的导入在 Dotnet 5.0 上编译良好。虽然没有按预期重新启动控制台应用程序...
      【解决方案5】:

      试试这样:

      // start new process
      System.Diagnostics.Process.Start(
           Environment.GetCommandLineArgs()[0], 
           Environment.GetCommandLineArgs()[1]);
      
      // close current process
      Environment.Exit(0);
      

      【讨论】:

        【解决方案6】:
        static void Main(string[] args)
        {
            var info = Console.ReadKey();
            if (info.Key == ConsoleKey.R)
            {
                var fileName = Assembly.GetExecutingAssembly().Location;
                System.Diagnostics.Process.Start(fileName);
            }
        }
        

        【讨论】:

          【解决方案7】:

          每个人都在想这个。试试这样的:

          class Program : IDisposable
          {
          
              class RestartException : Exception
              {
                  public RestartException() : base()
                  {
                  }
                  public RestartException( string message ) : base(message)
                  {
                  }
                  public RestartException( string message , Exception innerException) : base( message , innerException )
                  {
                  }
                  protected RestartException( SerializationInfo info , StreamingContext context ) : base( info , context )
                  {
                  }
              }
          
              static int Main( string[] argv )
              {
                  int  rc                      ;
                  bool restartExceptionThrown ;
          
                  do
                  {
                      restartExceptionThrown = false ;
                      try
                      {
                          using ( Program appInstance = new Program( argv ) )
                          {
                              rc = appInstance.Execute() ;
                          }
                      }
                      catch ( RestartException )
                      {
                          restartExceptionThrown = true ;
                      }
                  } while ( restartExceptionThrown ) ;
                  return rc ;
              }
          
              public Program( string[] argv )
              {
                  // initialization logic here
              }
          
              public int Execute()
              {
                  // core of your program here
                  DoSomething() ;
                  if ( restartNeeded )
                  {
                      throw new RestartException() ;
                  }
                  DoSomethingMore() ;
                  return applicationStatus ;
              }
          
              public void Dispose()
              {
                  // dispose of any resources used by this instance
              }
          
          }
          

          【讨论】:

          • 在声称每个人都在考虑解决方案的同时,过度思考你的答案,真是太棒了。
          【解决方案8】:

          我认为您确实不需要重新启动整个应用程序。只需按 R 后运行所需的方法即可。无需重新启动。

          【讨论】:

          • 好的,那么,这种情况下我需要调用方法:public static void Main(string[] args){},怎么调用呢?
          • 我不知道你的程序中有哪些方法/程序流程,但你总是可以从 Main 中提取代码、方法调用...
          • +1 @ale 你的问题应该更清楚,我想这就是你真正想要的。
          • 我不完全同意“我不认为你真的需要重启整个应用程序”。您真正需要的一种情况是,如果您有动态加载的程序集并且您想摆脱它们,因为显然 AppDomain 中没有程序集卸载功能。
          • @Visar 显然不是这种情况。
          【解决方案9】:
          // Starts a new instance of the program itself
          System.Diagnostics.Process.Start(Application.ExecutablePath);
          
          // Closes the current process
          Environment.Exit(0);
          

          【讨论】:

          • 对不起,我忘了它是一个控制台应用程序 - 应用程序是 Windows 窗体命名空间的一部分,而不是使用环境(我更新了代码)
          • 另外,整数0表示干净退出系统,link这里有其他人的列表,如果你有兴趣
          • 要点是:当发生异常时我想重新启动所有进程或启动 Main 方法,因为这个其他方法: public void DisplayMessage(string message) { Console.WriteLine(message, "Rebuild日志文件”); Console.WriteLine("按 Enter 完成,或按 R 重新启动程序...");字符串重启 = Console.ReadLine(); if(restart.ToUpper() == "R") { //调用 Main 方法或重启应用 } Console.ReadKey(); }
          【解决方案10】:

          启动第二个 exe 来结束控制台程序,启动一个新实例,然后自行结束?

          明确一点,代码是怎样的?

          这个命名空间应该有你需要的一切,如果这是你想要追求的解决方案。

          http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx

          【讨论】:

          • 要点是:当发生异常时我想重新启动所有进程或启动 Main 方法,因为这个其他方法: public void DisplayMessage(string message) { Console.WriteLine(message, "Rebuild日志文件”); Console.WriteLine("按 Enter 完成,或按 R 重新启动程序...");字符串重启 = Console.ReadLine(); if(restart.ToUpper() == "R") { //调用 Main 方法或重启应用 } Console.ReadKey(); }
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-30
          • 2017-05-21
          • 2017-01-29
          • 1970-01-01
          相关资源
          最近更新 更多