2009-08-06 36 views
6

Tôi đang tạo dự án C# winforms có thể chạy dưới dạng GUI hoặc có thể được vận hành từ dòng lệnh. Hiện tại, tôi có thể xử lý đầu vào dòng lệnh và đối số. Tôi có thể chạy chương trình từ dòng lệnh và tôi có thể sử dụng chương trình để xử lý các đối số. Nhưng Console.Writeline() hoàn toàn không có gì. Bất kỳ đầu mối nào có thể xảy ra?Console.Writeline() không hoạt động

+3

Xem ở đây: http://stackoverflow.com/questions/807998/how-do-i-create-ac-app-that-decides-itself-whether-to-show-as- a-console-or-wind – Thorarin

+0

Bạn có nghĩa là khi chạy chương trình của bạn trong chế độ dòng lệnh gọi Console.WriteLine dường như không thành công âm thầm? –

+0

bạn có thể thử dưới đây đơn giản - khoảng trống tĩnh Main (string [] args) { foreach (string arg in args) { Console.WriteLine (arg); } Console.ReadLine(); } hoạt động? – Mutant

Trả lời

6

Đối với hầu hết các phần, hãy xem answer here. Tuy nhiên, tôi muốn chỉ ra sự tồn tại của cuộc gọi API FreeConsole(), cho phép bạn đóng giao diện điều khiển một cách duyên dáng.

[DllImport("kernel32.dll")] 
static extern int FreeConsole() 

Một điều tôi muốn lưu ý: bạn có thể thấy một số weirdness của một dấu nhắc lệnh xuất hiện ở phía trước đầu ra giao diện điều khiển của bạn, nếu bạn đang tung ra từ một giao diện điều khiển hiện có và gắn với điều đó AttachConsole (như trái ngược với AllocConsole).

Đây là vấn đề về thời gian khó thực hiện. Nếu đó là sự cố, hãy đặt ứng dụng của bạn thành ứng dụng Console như những ứng dụng khác được đề xuất. Nó sẽ có tác dụng của không có dấu nhắc lệnh xuất hiện cho đến khi ứng dụng đóng cửa tuy nhiên, mà có thể không phải là những gì bạn muốn nếu bạn đang mở một winform.

Đáp lại bình luận của bạn: nó là một trong hai AttachConsolehoặcAllocConsole. Ví dụ tôi đã liên kết cố gắng đính kèm vào bảng điều khiển hiện có trước tiên. Nếu điều đó không thành công (rất có thể vì nó không tồn tại), nó sẽ tạo ra một cửa sổ giao diện điều khiển mới thay thế.

Nếu bạn tìm thấy cách để có những điều tốt nhất của cả hai thế giới về hành vi dòng lệnh và chế độ tương tác GUI, vui lòng cho tôi biết. Tôi đã không thực hiện bất kỳ tìm kiếm chuyên sâu cho một giải pháp, nhưng tôi có một vài ứng dụng nhỏ sẽ có lợi.

Nhân tiện: nếu bạn định sử dụng đường ống trên dòng lệnh của mình (chuyển hướng đầu ra sang tệp chẳng hạn), điều này sẽ không hoạt động như thế này.

+0

Giải pháp này hoạt động tốt. May mắn là tôi không cần đường ống. Cảm ơn bạn!! – novacara

0

Nó đã làm với các loại dự án như bạn cấu hình nó trên tab App trên các tính chất của dự án, bạn có 3 lựa chọn:

  • Console Application
  • Win Application
  • Class Library

Nếu bạn làm việc với ứng dụng Win, tuy nhiên, bạn cũng có thể xử lý các đối số dòng lệnh, vì chúng được nhận trên chức năng chính.

0

Dự án phải được thiết lập để biên dịch thành ứng dụng bảng điều khiển cho chức năng bàn điều khiển hoạt động. Mặt khác, nó sẽ luôn luôn có một cửa sổ giao diện điều khiển, ngay cả khi chạy như GUI. Tôi không biết một cách giải quyết cho điều này (nhưng sẽ được quan tâm để nghe về nó nếu có một).

3

Điều này là do bạn đã viết một ứng dụng winforms - điều này có nghĩa là System.Console.Out (tức là luồng đầu ra tiêu chuẩn) được đặt thành Stream.Null. Điều này có nghĩa là mọi cuộc gọi đến luồng đó sẽ không hoạt động âm thầm.

Bạn có thể xử lý đầu vào từ dòng lệnh vì chúng đến từ một luồng khác. Đạo đức của câu chuyện là bạn có thể có một ứng dụng winforms, hoặc một ứng dụng dòng lệnh, nhưng không phải cả hai cùng một lúc.

+0

Có, sắp xếp ... Các cuộc gọi API Windows để giải cứu :) – Thorarin

5

Bạn có thể bật giao diện điều khiển trong một ứng dụng dạng cửa sổ bằng cách sử dụng DllImports sau:

[DllImport("kernel32.dll")] 
    static extern bool AttachConsole(int dwProcessId); 
    private const int ATTACH_PARENT_PROCESS = -1; 

    [DllImport("kernel32.dll", SetLastError = true)] 
    internal static extern int FreeConsole(); 

Sau đó bạn có thể kích hoạt giao diện điều khiển sử dụng:

AttachConsole(ATTACH_PARENT_PROCESS); 

Và bạn có thể vô hiệu hóa nó bằng cách sử:

 FreeConsole(); 
2

Tôi đã làm điều này trong một chuỗi nền đang chạy một hàm từ một tải động DLL (phản ánh)

AllocConsole(); 
IntPtr stdHandle = GetStdHandle(STD_OUTPUT_HANDLE); 

StreamWriter standardOutput = new StreamWriter(Console.OpenStandardOutput()); 
standardOutput.AutoFlush = true; 
Console.SetOut(standardOutput); 
// 
//Console writing here 
// 
FreeConsole(); 

console của tôi là trống cho đến khi tôi được thêm vào Console.SetOut(), tôi không chắc chắn bạn cần phải gọi GetStdHandle()

+0

Cảm ơn, tôi đã có một AllocConsole đã làm việc một thời gian, và đột nhiên nó không còn nữa. Thêm Console.SetOut() đã làm thủ thuật! –

1

Bạn có thể cần phải thay đổi kiểu ứng dụng. Điều này có thể được thực hiện bằng một trong hai thay đổi nó thông qua Application Properties trong GUI (như đã giải thích trong answer từ ConsultUtah) hoặc bạn có thể chỉnh sửa các .csproj tập tin:

Winform/WPF:

<OutputType>WinExe</OutputType> 

Console (đây là những gì bạn cần cho console.writeline() được làm việc):

<OutputType>Exe</OutputType> 

DLL (bao gồm VI ỨNG DỤNG web ns):

<OutputType>Library</OutputType> 
Các vấn đề liên quan