2009-03-20 4 views
2

WinForm을 기반으로하는 C#을 명령 줄과 함께 사용하려고 노력하고 있습니다. 그러나 좋은 결과를 얻기가 어려워요. 예를 들어,이 코드가 있습니다윈도우 응용 프로그램에서 명령 줄에 쓰기

[STAThread] 
    static void Main(string[] args) { 
     foreach (string s in args) { 
      System.Windows.Forms.MessageBox.Show(s); 
      Console.WriteLine("String: " + s); 
     } 

     Mutex appSingleton = new System.Threading.Mutex(false, "WinSyncSingalInstanceMutx"); 
     if (appSingleton.WaitOne(0, false)) { 
      try { 
       Application.EnableVisualStyles(); 
       Application.SetCompatibleTextRenderingDefault(false); 

       //start logger 
       Logger.singleton.makeOpen(true); 
       Application.Run(new MainForm(false)); 
      } catch (Exception) { 
      } finally { 
       appSingleton.Close(); 
       Logger.singleton.makeOpen(false); 
      } 
     } else { 
      System.Windows.Forms.MessageBox.Show("Sorry, only one instance of WinSync can be ran at once."); 
     } 
    } 
} 

는 그것은 Console.WriteLine와 콘솔에 작성해야을,하지만 난 아무것도 볼 만 메시지 박스가 표시됩니다.

내가 뭘 잘못하고 있니?

답변

5

(-1) 나를 위해 일한,있는 console.out을 리디렉션 AttachConsole을 시도해보십시오

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace PEFixer 
{ 
    static class Program 
    { 
     [DllImport("kernel32.dll")] 
     private static extern bool AttachConsole(int dwProcessId); 

     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static int Main(string[] args) 
     { 
      if (args.Length > 0) 
      { 
       AttachConsole(-1); 
       return Form1.doTransformCmdLine(args); 
      } 
      else 
      { 
       Application.EnableVisualStyles(); 
       Application.SetCompatibleTextRenderingDefault(false); 
       Application.Run(new Form1()); 
      } 
      return 0; 
     } 
    } 
} 
+0

콘솔도 제대로 연결하지 못합니다. – Malfist

+0

가끔은 (!!?) 콘솔에 연결되지 않습니다. 이것은 관리 권한/etc와의 몇 가지 상호 작용 일 수 있습니다. 작동하지 않는 경우 cmd.exe를 다시 시작하면 도움이 될 수 있습니다. –

0

Visual Studio에서 디버그 모드 (F5)로 실행 중이거나 명령 줄에서 실행 중입니까? VS에서는 출력 탭 (Ctrl + Alt + O)에 콘솔 출력이 표시됩니다. 그렇지 않으면 쓸 콘솔이 없습니다.

+0

CMD.exe에서 실행 중입니다. – Malfist

+0

바보 같지만 Console.WriteLine에서 중단 점을 사용하여 디버깅 해보고 충돌 여부를 확인하십시오. 'foreach'는 명령 행에 인수가 없으면 코드를 호출하지 않습니다. –

2

Windows 응용 프로그램 모델은 약간 고통 스럽습니다. 응용 프로그램 유형을 콘솔 (등록 정보)로 변경해야하며 마술처럼 작동하기 시작해야합니다. 양식은 자동 생성 코드에 의해 명시 적으로 작성되므로 어쨌든 나타납니다.

+0

명령 줄에서 실행하면 작동하지만 VS에서 디버깅 할 때는 콘솔 만 표시됩니다. – Malfist

+0

그리고 명령 줄을 사용하지 않고 실행하면 명령 줄이 시작됩니다. : – Malfist

+0

그래, 이길 수 없어. 항상 명령 행을 가지거나 전혀하지 않겠지. ( – Grzenio

0

무엇을 사용해야합니까?

사용자가 콘솔을 볼 수 없으므로 디버깅 용이라면 Debug.WriteLine()을 사용하는 것이 좋습니다. 그때 문제없이 콘솔에 그것을해야한다 ...

+0

어쩌면 나는 gui없이 커맨드 라인을 통해 내 프로그램을 돌릴 수있는 방법이 있기를 원하기 때문에? – Malfist

+0

나는 이것에 대한 downvote가 가혹하다고 생각한다. (오늘의 표를 얻지 못하면,) –

+0

답변이 도움이되지 않는다면 downvote로되어 있는데, 도움이되지 못했습니다. 죄송합니다 – Malfist

2

내 제안은 콘솔을 얻기 위해 Windows 응용 프로그램을 만들고 나서 P/Invoke를 만드는 것이다. IE :

public Form1() 
{ 
    [DllImport("kernel32.dll")] 
    public static extern bool AllocConsole(); 

    [DllImport("kernel32.dll")] 
    public static extern bool FreeConsole(); 

    public Form1() 
    { 
     AllocConsole(); 
     Console.WriteLine("Whatever."); 
    } 
} 
+0

고마워요! 그러나 실제로 작동하지 않으면 AllocConsole을 호출해서는 안됩니다. 또한 콘솔에서 응용 프로그램을 실행하면 AllocConsole이 새 콘솔을 엽니 다. – Malfist

+0

네, 저는 그것을 실제로 보여 주었을뿐입니다. 실제로 생성자에서 수행해야하는 것은 아닙니다. 또한 Windows 응용 프로그램을 Windows 응용 프로그램으로 만들면 모든 Windows 구성 요소를 사용하고 콘솔 동작을 모방 한 AllocConsole을 사용하게됩니다. – BFree

+0

창 부품이 완성되었습니다. 리눅스에서 명령 행을 사용하는 데 익숙해지기 때문에 커맨드 라인 액세스를 추가하려고 노력하고 있습니다. 이것은 서버에 배포 될 예정이며 서비스로 실행해야 할 수도 있습니다. cron job – Malfist

1

을 AllocConsole 및 AttachConsole과주의 사항을이 함께 약간의 재생 및 본 후, 나는 생각한다 가장 좋은 방법은 두 개의 .NET exe 파일, 즉 foo.exe 및 fooconsole.exe를 사용하는 것입니다. 콘솔 출력이 필요하면 fooconsole.exe를 사용하십시오.

주요 기능 이외의 모든 코드는 DLL (클래스 라이브러리)을 생성하는 .NET 프로젝트에 배치 할 수 있습니다. 이것은 메인 윈도우를 포함하여 모든 win 폼을 포함합니다. exe 프로젝트에 남아있는 유일한 것은 차례대로 DLL에서 정적 함수를 호출하는 작은 주 기능입니다. 이 모든 작업은 P-Invoke에 의지하지 않고 수행 할 수 있습니다. 당신의 DLL 클래스 라이브러리에서

다음을 방출 프로젝트에서

using System; 

namespace MyNamespace 
{ 
    static class Program 
    { 
     [STAThread] 
     static int Main(string[] args) 
     { 
      return MainEntry.DoMain(args, false); 
     } 
    } 
} 

: 윈도우 EXE (에서 foo.exe)을 방출하는 프로젝트에서

using System; 
using System.Windows.Forms; 

namespace MyNamespace 
{ 
    public class MainEntry 
    { 
     private static bool mIsConsole = false; 

     private MainEntry() { } 

     public static bool IsConsoleApp 
     { 
      get { return mIsConsole; } 
     } 

     public static int DoMain(string[] args, bool isConsole) 
     { 
      mIsConsole = isConsole; 
      try 
      { 
       // do whatever - main program execution 
       return 0; // "Good" DOS return code 
      } 
      catch (Exception ex) 
      { 
       if (MainEntry.IsConsoleApp) 
       { 
        Console.Error.WriteLine(ex.Message); 
       } 
       else 
       { 
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } 
       return 1; // "Bad" DOS return code indicating failure 
      } 
     } 
    } 
} 

,이 유일한 코드 모두 EXE 프로젝트에서, 당신은 referen 필요 물론

using System; 

namespace MyNamespace 
{ 
    static class Program 
    { 
     [STAThread] 
     static int Main(string[] args) 
     { 
      return MainEntry.DoMain(args, true); 
     } 
    } 
} 

: 콘솔 EXE (fooconsole.exe)는,이 유일한 코드 ce 같은 솔루션에서 DLL 프로젝트에. 프로젝트 속성의 응용 프로그램 탭에서 프로젝트 유형 (Windows 응용 프로그램 (EXE), 콘솔 응용 프로그램 (EXE) 또는 클래스 라이브러리 (DLL))을 변경할 수 있습니다.

EXE 파일이 창이나 콘솔 서브 시스템을 사용하는지 프로그램 적으로 결정할 수는 있지만 P-Invoke가 많을 수도 있으므로 EXE 파일의 PE 헤더 바이트를 살펴 봐야합니다. .

또한, 명령 행이나 배치 파일에서 프로그램을 실행하고 출력 (stdout 및/또는 stderr)을 파일로 리디렉션하려고하면 AllocConsole/AttachConsole 메소드가 재미 있습니다. - 파일에는 가지 않을거야. http://www.nabble.com/WIN32:-Spawning-a-command-line-process-td21681465.html

또 다시 해결할 수는 있지만 더 많은 P-Invoke가 필요하며 그만한 가치는 없을 것입니다.

모범 사례로 DLL에서 정적 함수를 호출하는 간단한 Main 함수보다 EXE 프로젝트에 더 많은 것을 넣지 않았습니다. 많은 이유가 있지만 단 하나의 좋은 이유는 단위 테스트 도구가 EXE보다 DLL에서 더 잘 작동한다는 것입니다.

또한 args의 문자열 배열을 취하고 int를 반환하는 Main 함수의 형식에 유의하십시오. 배치 파일에서 ERRORLEVEL을 사용하면 EXE가 반환하는 모든 번호 (일반적으로 성공시 0, 실패시 0보다 큰 숫자)로 작업 할 수 있으므로이 형식을 사용하는 것이 가장 좋습니다.

관련 문제