Làm cách nào để hiển thị đầu ra / cửa sổ giao diện điều khiển trong ứng dụng biểu mẫu?


131

Để bị mắc kẹt ngay lập tức, một ví dụ rất cơ bản:

using System;
using System.Windows.Forms;

class test
{ 
    static void Main()
    { 
        Console.WriteLine("test");
        MessageBox.Show("test");
    }
}

Nếu tôi biên dịch cái này với các tùy chọn mặc định (sử dụng csc tại dòng lệnh), như mong đợi, nó sẽ biên dịch sang ứng dụng console. Ngoài ra, vì tôi đã nhập System.Windows.Forms, nó cũng sẽ hiển thị một hộp thông báo.

Bây giờ, nếu tôi sử dụng tùy chọn /target:winexe, mà tôi nghĩ giống như chọn Windows Applicationtrong các tùy chọn dự án, như mong đợi, tôi sẽ chỉ thấy Hộp thông báo và không có đầu ra giao diện điều khiển.

(Trong thực tế, thời điểm nó được khởi chạy từ dòng lệnh, tôi có thể đưa ra lệnh tiếp theo trước khi ứng dụng thậm chí đã hoàn thành).

Vì vậy, câu hỏi của tôi là - Tôi biết rằng bạn có thể có "cửa sổ" / hình thức đầu ra từ một ứng dụng bảng điều khiển, nhưng dù sao cũng có thể hiển thị bảng điều khiển từ một ứng dụng Windows?


2
Bạn thấy gì về sự khác biệt giữa hai? Tại sao không chỉ biên dịch như bàn điều khiển và hiển thị một hình thức.
Doggett

7
@Doggett, đơn giản - Tôi đang tìm hiểu và muốn hiểu tại sao / làm thế nào để làm điều đó, ngay cả khi tôi không bao giờ kết thúc việc sử dụng nó trong một ứng dụng thực tế .... Hiện tại, tôi đang nghĩ đến một tùy chọn cung cấp thêm lệnh / đầu ra như trong VLC, tuy nhiên TBH, tôi không cần nó - một lần nữa, chỉ cần học và muốn hiểu nó!
Wil

Tôi đã hoàn thành việc sử dụng hướng dẫn này: saezndaree.wordpress.com/2009/03/29/ trên
vivanov

Câu trả lời:


153

cái này nên hoạt động

using System.Runtime.InteropServices;

private void Form1_Load(object sender, EventArgs e)
{
    AllocConsole();
}

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();

8
Thật tuyệt vời, câu hỏi này dường như đã được hỏi rất nhiều, đây là câu trả lời thực tế duy nhất cho câu hỏi tôi có thể tìm thấy, +1
RobJohnson

5
Vấn đề chính: khi bạn đóng nó, tất cả các ứng dụng sẽ đóng lại.
Đánh dấu

4
Tôi đã thử nghiệm trên Windows 8 và Windows 10: - AttachConsole hoạt động từ hộp cmd - AllocConsole hoạt động từ Visual Studio. Khi cần phân bổ, AttachConsole trả về false. Bạn cũng nên gọi FreeConsole () trước khi kết thúc ứng dụng ở chế độ bảng điều khiển. Trong chương trình của mình, tôi đã sử dụng mã của Matthew Strawbridge (xem bên dưới), với dòng AttachConsole () được sửa đổi thành: if (! AttachConsole (-1)) AllocConsole ();
Berend Engelbrecht

Điều này sẽ làm việc trong một điều khiển người dùng? Tôi đang làm việc để tạo một điều khiển SSH như một thành phần winforms bằng Granados (ví dụ) và nó chỉ là thành phần nền. Tôi muốn thêm một trình bao bọc đẹp cho nó để hiển thị và sử dụng bàn điều khiển trong một thành phần.
Kraang Prime

2
Điều này không tốt lắm, khi chạy từ dòng lệnh, nó sẽ mở một cửa sổ giao diện điều khiển riêng và khi chạy từ dòng lệnh và cố gắng sử dụng >để chuyển hướng đầu ra, tôi nhận được một cửa sổ giao diện điều khiển riêng và đầu ra bằng 0 trong tệp của mình.
uglycoyote

139

Có lẽ điều này là quá đơn giản ...

Tạo một dự án Windows Form ...

Sau đó: Thuộc tính dự án -> Ứng dụng -> Loại đầu ra -> Ứng dụng bảng điều khiển

Sau đó, có thể có Bảng điều khiển và Biểu mẫu chạy cùng nhau, hoạt động với tôi


2
Có vẻ đơn giản nhất, khắc phục vấn đề của tôi là tốt.
Dadude999

2
Đây chắc chắn là giải pháp tốt nhất! Những người khác thì thông minh nhưng lại phức tạp
LM.Croisez

3
Đơn giản và làm việc tốt. Đây phải là câu trả lời được chấp nhận.
madu

7
Trong khi, vâng, về mặt kỹ thuật, điều này có thể được sử dụng để cho phép những gì người đăng đang yêu cầu - đó không phải là một giải pháp tuyệt vời. Bằng cách này, nếu sau đó bạn khởi động ứng dụng winforms của mình với GUI - bạn cũng sẽ mở được cửa sổ giao diện điều khiển. Trong trường hợp này, bạn sẽ cần một cái gì đó giống như câu trả lời của Mike de Klerk.
Justin Greywolf

2
Đây là giải pháp duy nhất mà tôi có thể lấy ứng dụng Winforms của mình để ghi đầu ra vào bàn điều khiển khi chạy từ dòng lệnh hoặc ghi vào tệp khi được chuyển hướng trên dòng lệnh >. Tuy nhiên, tôi đã hy vọng một giải pháp sẽ giải thích cách chạy như một "Ứng dụng bảng điều khiển" chỉ một lúc nào đó (nghĩa là cho phép lập trình kích hoạt bất cứ điều gì thay đổi cài đặt Visual Studio bí ẩn này). Có ai biết làm thế nào điều này hoạt động dưới mui xe?
uglycoyote

63

Nếu bạn không lo lắng về việc mở một bảng điều khiển theo lệnh, bạn có thể đi vào các thuộc tính cho dự án của bạn và thay đổi nó thành Ứng dụng Bảng điều khiển

ảnh chụp màn hình thay đổi loại dự án.

Điều này sẽ vẫn hiển thị biểu mẫu của bạn cũng như bật lên một cửa sổ giao diện điều khiển. Bạn không thể đóng cửa sổ giao diện điều khiển, nhưng nó hoạt động như một trình ghi nhật ký tạm thời tuyệt vời để gỡ lỗi.

Chỉ cần nhớ tắt nó trước khi bạn triển khai chương trình.


1
Đẹp. Điều này giải quyết vấn đề tôi gặp phải với ứng dụng biểu mẫu của mình, rằng tôi cần có thể xuất ra cửa sổ giao diện điều khiển trong khi hỗ trợ chuyển hướng đầu ra sang tệp. Và tôi không cần phải đính kèm bất kỳ bàn điều khiển nào bằng tay ...
Kai Hartmann

2
@JasonHarrison Nếu bạn đóng cửa sổ giao diện điều khiển, chương trình sẽ đóng lại. Ngoài ra cửa sổ luôn mở trong khi chương trình chạy.
gunr2171

2
@ súng2171: Cảm ơn. Nhược điểm của phương pháp này được ghi chú trong câu trả lời: cửa sổ giao diện điều khiển sẽ xuất hiện nếu ứng dụng được khởi chạy với nhấp đúp chuột, menu Bắt đầu, v.v.
Jason Harrison

17

Bạn có thể gọi AttachConsolebằng cách sử dụng pinvoke để có cửa sổ giao diện điều khiển được đính kèm với dự án WinForms: http://www.csharp411.com/console-output-from-winforms-application/

Bạn cũng có thể muốn xem xét Log4net ( http://logging.apache.org/log4net/index.html ) để định cấu hình đầu ra nhật ký theo các cấu hình khác nhau.


+1 - Wow, tôi đã hy vọng cho một console.show hoặc tương tự! phức tạp hơn tôi nghĩ Tôi sẽ để ngỏ cho hiện tại chỉ trong trường hợp có câu trả lời tốt hơn / dễ dàng hơn.
Wil

Điều này làm việc với tôi, AllocConsole () không phải vì nó sinh ra một cửa sổ giao diện điều khiển mới (không đào sâu hơn vào AllocConsole, có lẽ tôi đã bỏ lỡ điều gì đó ở đó).
derFunk

14

Điều này làm việc cho tôi, để chuyển đầu ra thành một tập tin. Gọi bàn điều khiển với

cmd / c "C: \ path \ to \ your \ application.exe"> myfile.txt

Thêm mã này vào ứng dụng của bạn.

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool GetFileInformationByHandle(
        SafeFileHandle hFile,
        out BY_HANDLE_FILE_INFORMATION lpFileInformation
        );
    [DllImport("kernel32.dll")]
    private static extern SafeFileHandle GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(UInt32 nStdHandle, SafeFileHandle hHandle);
    [DllImport("kernel32.dll")]
    private static extern bool DuplicateHandle(
        IntPtr hSourceProcessHandle,
        SafeFileHandle hSourceHandle,
        IntPtr hTargetProcessHandle,
        out SafeFileHandle lpTargetHandle,
        UInt32 dwDesiredAccess,
        Boolean bInheritHandle,
        UInt32 dwOptions
        );
    private const UInt32 ATTACH_PARENT_PROCESS = 0xFFFFFFFF;
    private const UInt32 STD_OUTPUT_HANDLE = 0xFFFFFFF5;
    private const UInt32 STD_ERROR_HANDLE = 0xFFFFFFF4;
    private const UInt32 DUPLICATE_SAME_ACCESS = 2;
    struct BY_HANDLE_FILE_INFORMATION
    {
        public UInt32 FileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
        public UInt32 VolumeSerialNumber;
        public UInt32 FileSizeHigh;
        public UInt32 FileSizeLow;
        public UInt32 NumberOfLinks;
        public UInt32 FileIndexHigh;
        public UInt32 FileIndexLow;
    }
    static void InitConsoleHandles()
    {
        SafeFileHandle hStdOut, hStdErr, hStdOutDup, hStdErrDup;
        BY_HANDLE_FILE_INFORMATION bhfi;
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        hStdErr = GetStdHandle(STD_ERROR_HANDLE);
        // Get current process handle
        IntPtr hProcess = Process.GetCurrentProcess().Handle;
        // Duplicate Stdout handle to save initial value
        DuplicateHandle(hProcess, hStdOut, hProcess, out hStdOutDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Duplicate Stderr handle to save initial value
        DuplicateHandle(hProcess, hStdErr, hProcess, out hStdErrDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Attach to console window – this may modify the standard handles
        AttachConsole(ATTACH_PARENT_PROCESS);
        // Adjust the standard handles
        if (GetFileInformationByHandle(GetStdHandle(STD_OUTPUT_HANDLE), out bhfi))
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOutDup);
        }
        else
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOut);
        }
        if (GetFileInformationByHandle(GetStdHandle(STD_ERROR_HANDLE), out bhfi))
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErrDup);
        }
        else
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErr);
        }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // initialize console handles
        InitConsoleHandles();

        if (args.Length != 0)
        {

            if (args[0].Equals("waitfordebugger"))
            {
                MessageBox.Show("Attach the debugger now");
            }
            if (args[0].Equals("version"))
            {
#if DEBUG
                String typeOfBuild = "d";
#else
                String typeOfBuild = "r";
#endif
                String output = typeOfBuild + Assembly.GetExecutingAssembly()
                    .GetName().Version.ToString();
                //Just for the fun of it
                Console.Write(output);
                Console.Beep(4000, 100);
                Console.Beep(2000, 100);
                Console.Beep(1000, 100);
                Console.Beep(8000, 100);
                return;
            }
        }
    }

Tôi tìm thấy mã này ở đây: http://www.csharp411.com/console-output-from-winforms-application/ Tôi nghĩ cũng đáng để đăng nó ở đây.


5
Điều này hoạt động rất tốt NGOẠI TRỪ nó hiện thất bại trong Windows 8 và Windows 10. Do thất bại, ý tôi là không có đầu ra ngoại trừ và dấu nhắc thêm (nếu đó là một đầu mối). Một số người đã đề xuất AllocConsole nhưng nó chỉ nháy một cửa sổ cmd.
Simon Heffer

Cũng đã thử câu trả lời của Chaz ở trên nhưng điều đó mang lại một giao diện điều khiển mới trong Windows 7 (không phải trong 8 hoặc 10). Tôi chỉ cần tùy chọn để chạy với chuyển hướng trên dòng lệnh hoặc chạy như một gui nếu không có đối số.
Simon Heffer

Tôi đã thử điều này nhưng không hiệu quả. Chỉ cần AttachConsole(ATTACH_PARENT_PROCESS)tôi nhận được đầu ra giao diện điều khiển nhưng chuyển hướng nó trên dòng lệnh >không hoạt động. Khi tôi thử câu trả lời này, tôi không thể nhận được bất kỳ đầu ra nào, trong bảng điều khiển hoặc trong một tệp.
uglycoyote

12

Về cơ bản có hai điều có thể xảy ra ở đây.

Đầu ra giao diện điều khiển Có thể chương trình winforms tự gắn vào cửa sổ giao diện điều khiển đã tạo ra nó (hoặc với một cửa sổ giao diện điều khiển khác, hoặc thực sự với một cửa sổ giao diện điều khiển mới nếu muốn). Sau khi được gắn vào cửa sổ giao diện điều khiển Console.WriteLine () vv hoạt động như mong đợi. Một điều đáng chú ý đối với phương pháp này là chương trình trả lại quyền điều khiển cho cửa sổ giao diện điều khiển ngay lập tức và sau đó tiếp tục ghi vào nó, vì vậy người dùng cũng có thể gõ vào cửa sổ giao diện điều khiển. Bạn có thể sử dụng bắt đầu với tham số / Wait để xử lý điều này tôi nghĩ.

Liên kết để bắt đầu Cú pháp lệnh

Đầu ra giao diện điều khiển được chuyển hướng Đây là khi ai đó chuyển đầu ra từ chương trình của bạn sang một nơi khác, ví dụ.

yourapp> file.txt

Gắn vào cửa sổ bàn điều khiển trong trường hợp này có hiệu quả bỏ qua đường ống. Để thực hiện công việc này, bạn có thể gọi Console.OpenSt ChuẩnOutput () để xử lý luồng mà đầu ra sẽ được dẫn đến. Điều này chỉ hoạt động nếu đầu ra được dẫn, vì vậy nếu bạn muốn xử lý cả hai tình huống bạn cần mở đầu ra tiêu chuẩn và ghi vào nó và gắn vào cửa sổ giao diện điều khiển. Điều này không có nghĩa là đầu ra được gửi đến cửa sổ giao diện điều khiển và tới đường ống nhưng đó là giải pháp tốt nhất tôi có thể tìm thấy. Dưới mã tôi sử dụng để làm điều này.

// This always writes to the parent console window and also to a redirected stdout if there is one.
// It would be better to do the relevant thing (eg write to the redirected file if there is one, otherwise
// write to the console) but it doesn't seem possible.
public class GUIConsoleWriter : IConsoleWriter
{
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int dwProcessId);

    private const int ATTACH_PARENT_PROCESS = -1;

    StreamWriter _stdOutWriter;

    // this must be called early in the program
    public GUIConsoleWriter()
    {
        // this needs to happen before attachconsole.
        // If the output is not redirected we still get a valid stream but it doesn't appear to write anywhere
        // I guess it probably does write somewhere, but nowhere I can find out about
        var stdout = Console.OpenStandardOutput();
        _stdOutWriter = new StreamWriter(stdout);
        _stdOutWriter.AutoFlush = true;

        AttachConsole(ATTACH_PARENT_PROCESS);
    }

    public void WriteLine(string line)
    {
        _stdOutWriter.WriteLine(line);
        Console.WriteLine(line);
    }
}

Tôi đã không thể viết lên bàn điều khiển; đính kèm quá trình cha mẹ đầu tiên đã làm thủ thuật. Cảm ơn bạn.
Học sinh

Dường như câu trả lời này yêu cầu bạn viết lại tất cả các cuộc gọi Console.WriteLineđể thay vào đó gọi cuộc gọi mới WriteLineđược xác định ở trên. Mặc dù tôi đã cố gắng rằng tôi không thể với mã này để nhận bất kỳ thứ gì được chuyển hướng đến một tệp khi chạy ứng dụng trên dòng lệnh và chuyển hướng >đến một tệp.
uglycoyote

@uglycoyote, hãy đảm bảo rằng bạn đang xây dựng GUIConsoleWriter càng sớm càng tốt trong ứng dụng của mình, nếu không nó sẽ không hoạt động vì lý do loại cửa sổ bí ẩn. Tôi cho rằng việc đóng gói các cuộc gọi Console.WriteLinechỉ là một cách thực hành tốt, vì nó cho phép bạn kiểm tra và dễ dàng thay đổi các địa điểm mà bạn đăng nhập (ví dụ: bạn có thể muốn bắt đầu đăng nhập vào dịch vụ ghi nhật ký dựa trên đám mây như PaperTrail hoặc bất cứ điều gì )
cedd

điều này làm việc tốt với tôi trong Win10 mà không cầnStreamWriter _stdOutWriter;
TS

Đường ống là câu trả lời, nhưng thay vì vào một tệp, chỉ cần sử dụng THÊM, như: yourapp | hơn ; vui lòng tham khảo stackoverflow.com/a/13010823/1845672
Roland

9

Tạo Ứng dụng Windows Forms và thay đổi loại đầu ra thành Bảng điều khiển.

Nó sẽ dẫn đến cả một giao diện điều khiển và hình thức để mở.

nhập mô tả hình ảnh ở đây


Đây chính xác là những gì tôi đang tìm kiếm. Đơn giản và không sử dụng WINAPI.
Michael Coxon

Tôi đã thử nhiều ví dụ, nhưng không ai trong số họ tạo ra kết quả đáp ứng mong đợi của tôi. Tuy nhiên, giải pháp này chính xác là những gì tôi muốn và cho đến nay là giải pháp đơn giản nhất.
inexcitus

4
//From your application set the Console to write to your RichTextkBox 
//object:
Console.SetOut(new RichTextBoxWriter(yourRichTextBox));

//To ensure that your RichTextBox object is scrolled down when its text is 
//changed add this event:
private void yourRichTextBox_TextChanged(object sender, EventArgs e)
{
    yourRichTextBox.SelectionStart = yourRichTextBox.Text.Length;
    yourRichTextBox.ScrollToCaret();
}

public delegate void StringArgReturningVoidDelegate(string text);
public class RichTextBoxWriter : TextWriter
{
    private readonly RichTextBox _richTextBox;
    public RichTextBoxWriter(RichTextBox richTexttbox)
    {
        _richTextBox = richTexttbox;
    }

    public override void Write(char value)
    {
        SetText(value.ToString());
    }

    public override void Write(string value)
    {
        SetText(value);
    }

    public override void WriteLine(char value)
    {
        SetText(value + Environment.NewLine);
    }

    public override void WriteLine(string value)
    {
        SetText(value + Environment.NewLine);
    }

    public override Encoding Encoding => Encoding.ASCII;

    //Write to your UI object in thread safe way:
    private void SetText(string text)
    {
        // InvokeRequired required compares the thread ID of the  
        // calling thread to the thread ID of the creating thread.  
        // If these threads are different, it returns true.  
        if (_richTextBox.InvokeRequired)
        {
            var d = new StringArgReturningVoidDelegate(SetText);
            _richTextBox.Invoke(d, text);
        }
        else
        {
            _richTextBox.Text += text;
        }
    }
}

3
using System;
using System.Runtime.InteropServices;

namespace SomeProject
{
    class GuiRedirect
    {
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool AttachConsole(int dwProcessId);
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetStdHandle(StandardHandle nStdHandle);
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle);
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern FileType GetFileType(IntPtr handle);

    private enum StandardHandle : uint
    {
        Input = unchecked((uint)-10),
        Output = unchecked((uint)-11),
        Error = unchecked((uint)-12)
    }

    private enum FileType : uint
    {
        Unknown = 0x0000,
        Disk = 0x0001,
        Char = 0x0002,
        Pipe = 0x0003
    }

    private static bool IsRedirected(IntPtr handle)
    {
        FileType fileType = GetFileType(handle);

        return (fileType == FileType.Disk) || (fileType == FileType.Pipe);
    }

    public static void Redirect()
    {
        if (IsRedirected(GetStdHandle(StandardHandle.Output)))
        {
            var initialiseOut = Console.Out;
        }

        bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error));
        if (errorRedirected)
        {
            var initialiseError = Console.Error;
        }

        AttachConsole(-1);

        if (!errorRedirected)
            SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output));
    }
}

1
Hoạt động tốt từ một dấu nhắc lệnh, nhưng không phải từ Start> Run hoặc trong Visual Studio. Để làm cho nó hoạt động trong mọi trường hợp, hãy thay thế dòng AttachConsole bằng: if (! AttachConsole (-1)) AllocConsole (); Nếu AllocConsole () được gọi, FreeConsole () cũng sẽ được gọi, nếu không thì máy chủ console tiếp tục chạy sau khi kết thúc chương trình.
Berend Engelbrecht

2
Mục đích sử dụng của initiseOut và initiseError là gì, vì chúng không được sử dụng?
Edwin

StandardHandle : uintlà sai ở đây ... nên là IntPtr để hoạt động cả trên x86 và x64
Dmitry Gusarov

1

Bạn có thể chuyển đổi bất kỳ lúc nào giữa các loại ứng dụng, sang bàn điều khiển hoặc cửa sổ. Vì vậy, bạn sẽ không viết logic đặc biệt để xem thiết bị xuất chuẩn. Ngoài ra, khi chạy ứng dụng trong trình gỡ lỗi, bạn sẽ thấy tất cả các thiết bị xuất chuẩn trong cửa sổ đầu ra. Bạn cũng có thể chỉ cần thêm một điểm dừng và trong các thuộc tính điểm dừng thay đổi "Khi nhấn ...", bạn có thể xuất bất kỳ thông báo và biến nào. Ngoài ra, bạn có thể kiểm tra / bỏ chọn "Tiếp tục thực hiện" và điểm dừng của bạn sẽ trở thành hình vuông. Vì vậy, các thông báo điểm dừng mà không thay đổi bất cứ điều gì trong ứng dụng trong cửa sổ đầu ra gỡ lỗi.


0

Tại sao không chỉ để nó dưới dạng ứng dụng Window Forms và tạo một biểu mẫu đơn giản để bắt chước Bảng điều khiển. Biểu mẫu có thể được thực hiện để trông giống như Bảng điều khiển màn hình đen và để nó phản hồi trực tiếp với phím bấm. Sau đó, trong tệp chương trình.cs, bạn quyết định xem bạn cần Chạy biểu mẫu chính hay ConsoleForm. Ví dụ, tôi sử dụng cách tiếp cận này để nắm bắt các đối số dòng lệnh trong tệp chương trình.cs. Tôi tạo ConsoleForm, ban đầu ẩn nó, sau đó chuyển các chuỗi dòng lệnh cho hàm AddCommand trong đó, hiển thị các lệnh được phép. Cuối cùng, nếu người dùng đã cho -h hoặc -? lệnh, tôi gọi .Show trên ConsoleForm và khi người dùng nhấn bất kỳ phím nào trên đó, tôi tắt chương trình. Nếu người dùng không cung cấp cho -? lệnh, tôi đóng ConsoleForm ẩn và Chạy biểu mẫu chính.


2
Xin chào và chào mừng bạn đến với StackOverflow, tránh đăng câu hỏi dưới dạng câu trả lời, hãy sử dụng phần bình luận.
Pedro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.