매우 기본적인 예를 바로 잡으려면 :
using System;
using System.Windows.Forms;
class test
{
static void Main()
{
Console.WriteLine("test");
MessageBox.Show("test");
}
}
기본 옵션 (명령 줄에서 csc 사용)으로 이것을 컴파일하면 콘솔 응용 프로그램으로 컴파일됩니다. 또한 내가 가져 오기 때문에 System.Windows.Forms
메시지 상자도 표시됩니다.
이제 프로젝트 옵션 내에서 /target:winexe
선택하는 것과 동일한 Windows Application
옵션을 사용하면 예상대로 메시지 상자 만 표시되고 콘솔 출력은 표시되지 않습니다.
(사실, 명령 줄에서 시작된 순간, 응용 프로그램이 완료되기 전에 다음 명령을 실행할 수 있습니다).
그래서 내 질문은-콘솔 응용 프로그램에서 “windows”/ forms 출력을 가질 수 있지만 Windows 응용 프로그램에서 콘솔을 표시 할 수 있다는 것을 알고 있습니다.
답변
이것은 작동해야합니다.
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();
답변
아마도 이것은 지나치게 단순한 것입니다 …
Windows Form 프로젝트 만들기 …
그런 다음 프로젝트 특성-> 응용 프로그램-> 출력 유형-> 콘솔 응용 프로그램
그런 다음 콘솔과 양식을 함께 실행할 수 있습니다.
답변
콘솔 명령을 여는 것에 대해 걱정하지 않으면 프로젝트의 속성으로 이동하여 콘솔 응용 프로그램으로 변경할 수 있습니다
이것은 콘솔 창을 팝업 할뿐만 아니라 여전히 양식을 보여줍니다. 콘솔 창을 닫을 수는 없지만 디버깅을위한 훌륭한 임시 로거로 작동합니다.
프로그램을 배포하기 전에 다시 끄십시오.
답변
AttachConsole
pinvoke를 사용하여 호출 하여 WinForms 프로젝트에 연결된 콘솔 창을 얻을 수 있습니다 . http://www.csharp411.com/console-output-from-winforms-application/
다른 구성으로 로그 출력을 구성하기 위해 Log4net ( http://logging.apache.org/log4net/index.html ) 을 고려할 수도 있습니다 .
답변
이것은 출력을 파일로 파이프하는 데 효과적이었습니다. 와 함께 콘솔을 호출
cmd / c “C : \ path \ to \ your \ application.exe”> myfile.txt
이 코드를 응용 프로그램에 추가하십시오.
[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;
}
}
}
나는이 코드를 여기에서 발견했다 : http://www.csharp411.com/console-output-from-winforms-application/
나는 여기에 그것을 게시 할 가치가 있다고 생각했다.
답변
기본적으로 여기서 발생할 수있는 두 가지가 있습니다.
콘솔 출력 winforms 프로그램이 자신을 생성 한 콘솔 창 (또는 다른 콘솔 창 또는 원하는 경우 새 콘솔 창)에 연결될 수 있습니다. 콘솔 창에 연결되면 Console.WriteLine () 등이 예상대로 작동합니다. 이 접근 방식의 한 가지 단점은 프로그램이 즉시 제어를 콘솔 창으로 리턴 한 다음 계속해서 작성하여 사용자가 콘솔 창에 입력 할 수 있다는 것입니다. / wait 매개 변수로 start를 사용하여이 문제를 처리 할 수 있습니다.
리디렉션 된 콘솔 출력 누군가가 프로그램의 출력을 다른 곳으로 파이프하는 경우입니다 (예 :
yourapp> file.txt
이 경우 콘솔 창에 부착하면 배관을 효과적으로 무시합니다. 이 작업을 수행하려면 Console.OpenStandardOutput ()을 호출하여 출력을 파이프해야하는 스트림에 대한 핸들을 얻을 수 있습니다. 이것은 출력이 파이프 된 경우에만 작동하므로 두 시나리오를 모두 처리하려면 표준 출력을 열고 출력하고 콘솔 창에 연결해야합니다. 이것은 출력이 콘솔 창과 파이프로 보내지지만 내가 찾을 수있는 최상의 솔루션이라는 것을 의미합니다. 이 작업을 수행하는 데 사용하는 코드 아래.
// 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);
}
}
