How do I create a C# app that decides itself whether to show as a console or windowed app?

前端 未结 11 789
广开言路
广开言路 2020-11-28 21:10

Is there a way to launch a C# application with the following features?

  1. It determines by command-line parameters whether it is a windowed or console app
11条回答
  •  自闭症患者
    2020-11-28 21:12

    The important thing to remember to do after AttachConsole() or AllocConsole() calls to get it to work in all cases is:

    if (AttachConsole(ATTACH_PARENT_PROCESS))
      {
        System.IO.StreamWriter sw =
          new System.IO.StreamWriter(System.Console.OpenStandardOutput());
        sw.AutoFlush = true;
        System.Console.SetOut(sw);
        System.Console.SetError(sw);
      }
    

    I have found that works with or without VS hosting process. With output being sent with System.Console.WriteLine or System.Console.out.WriteLine before call To AttachConsole or AllocConsole. I have included my method below:

    public static bool DoConsoleSetep(bool ClearLineIfParentConsole)
    {
      if (GetConsoleWindow() != System.IntPtr.Zero)
      {
        return true;
      }
      if (AttachConsole(ATTACH_PARENT_PROCESS))
      {
        System.IO.StreamWriter sw = new System.IO.StreamWriter(System.Console.OpenStandardOutput());
        sw.AutoFlush = true;
        System.Console.SetOut(sw);
        System.Console.SetError(sw);
        ConsoleSetupWasParentConsole = true;
        if (ClearLineIfParentConsole)
        {
          // Clear command prompt since windows thinks we are a windowing app
          System.Console.CursorLeft = 0;
          char[] bl = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.Repeat(' ', System.Console.WindowWidth - 1));
          System.Console.Write(bl);
          System.Console.CursorLeft = 0;
        }
        return true;
      }
      int Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
      if (Error == ERROR_ACCESS_DENIED)
      {
        if (log.IsDebugEnabled) log.Debug("AttachConsole(ATTACH_PARENT_PROCESS) returned ERROR_ACCESS_DENIED");
        return true;
      }
      if (Error == ERROR_INVALID_HANDLE)
      {
        if (AllocConsole())
        {
          System.IO.StreamWriter sw = new System.IO.StreamWriter(System.Console.OpenStandardOutput());
          sw.AutoFlush = true;
          System.Console.SetOut(sw);
          System.Console.SetError(sw);
          return true;
        }
      }
      return false;
    }
    

    I also called this when I was done in case I needed command prompt to redisplay when I was done doing output.

    public static void SendConsoleInputCR(bool UseConsoleSetupWasParentConsole)
    {
      if (UseConsoleSetupWasParentConsole && !ConsoleSetupWasParentConsole)
      {
        return;
      }
      long LongNegOne = -1;
      System.IntPtr NegOne = new System.IntPtr(LongNegOne);
      System.IntPtr StdIn = GetStdHandle(STD_INPUT_HANDLE);
      if (StdIn == NegOne)
      {
        return;
      }
      INPUT_RECORD[] ira = new INPUT_RECORD[2];
      ira[0].EventType = KEY_EVENT;
      ira[0].KeyEvent.bKeyDown = true;
      ira[0].KeyEvent.wRepeatCount = 1;
      ira[0].KeyEvent.wVirtualKeyCode = 0;
      ira[0].KeyEvent.wVirtualScanCode = 0;
      ira[0].KeyEvent.UnicodeChar = '\r';
      ira[0].KeyEvent.dwControlKeyState = 0;
      ira[1].EventType = KEY_EVENT;
      ira[1].KeyEvent.bKeyDown = false;
      ira[1].KeyEvent.wRepeatCount = 1;
      ira[1].KeyEvent.wVirtualKeyCode = 0;
      ira[1].KeyEvent.wVirtualScanCode = 0;
      ira[1].KeyEvent.UnicodeChar = '\r';
      ira[1].KeyEvent.dwControlKeyState = 0;
      uint recs = 2;
      uint zero = 0;
      WriteConsoleInput(StdIn, ira, recs, out zero);
    }
    

    Hope this helps...

提交回复
热议问题