누군가가 C#에서 Windows 콘솔 응용 프로그램의 핸들을 가져 오는 방법을 말해 줄 수 있습니까? Windows Forms 응용 프로그램에서는 일반적으로 this.Handle
을 시도합니다.콘솔 응용 프로그램 창의 핸들을 얻는 방법
답변
는 확실하지가 작동하지만 당신은 시도 할 수 있습니다 :
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
그런 일은 없을 것이라고 생각합니다. 응용 프로그램에서 콘솔 창에 액세스 할 수 없습니다. 자신의 프로세스 이름을 찾는 프로세스 목록을 반복하려고 할 수도 있습니다. Process
클래스 IIRC에는 프로그램의 주 창 핸들에 대한 속성이 포함되어 있습니다. 일 수 있습니다.은 콘솔 응용 프로그램의 콘솔 창입니다. 잘 모르겠습니다.
"자신의 프로세스 이름을 찾는 프로세스 목록을 반복하십시오"=> 매우 효율적인 접근법이 아닙니다 ... PID를 사용하여 찾을 수 있습니다.} –
Whoops - Thomas Levesque의 대답은 훨씬 더 우아합니다.동일한 속성에 의존하면서 반복 할 필요가 없습니다. 나는 현재 프로세스에 직접 액세스 할 수 있다는 것을 잊었습니다. –
@Thomas : 죄송합니다. 전에 귀하의 코멘트를 보지 못했습니다. 물론 반복은 훨씬 비효율적입니다. GetCurrentProcess() 메서드를 기억하지 못했습니다 ... –
이 시도 : 난 그냥 나 자신 (이 문제를 해결했습니다
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);
…
Console.Title = "Test";
…
IntPtr handle = FindWindowByCaption(IntPtr.Zero, Console.Title);
을 불행하게도 더 빨리되는 Thomas's answer을보기 전에). 글쎄, 그의 대답에 만족하지 않는 사람들을위한 또 다른 방법이있다. 이 답을 쓰고 있는데 왜냐하면 콘솔을 윈도우로 다루는 경우 Program
클래스를 디자인하는 또 다른 대답 + 더 좋은 방법을 제공하고 싶기 때문입니다. 그 디자인부터 시작해 보겠습니다.
Program
클래스의 기본 스타일이 변경되었습니다. 저는 실제로 프로그램을 가지고있는 클래스에 그것을 만들었습니다. 그리고 그것을 표현하고 다른 클래스를 컨텐트에 사용하는 하나의 메소드가 아닙니다. (당신이 무슨 뜻인지 모르는 경우 중요하지 않습니다.)
나는 다음과 같은 이벤트 핸들러 쓰고 싶었 기 때문에 내가이해야 할 일을했을 이유 :이 방법 MessageBox.Show(IWin32Window, String, String)
를 오버로드
private void CatchUnhandled(Object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
MessageBox.Show(this, exception.Message, "Error"); // Check out 1st arg.
}
합니다. 콘솔 IWin32Window
를 구현하지 않기 때문에
, 난 그냥 1 일 인수에 this
를 호출하기 위해, 물론, 그것을 자신을 구현했다.
참고 :이 코드는 사용자가 액세스 수정을 자유롭게 변경할 느낄 수있는, 내 응용 프로그램에서 붙여 넣은 복사입니다
Program
클래스 선언 다음
은 그것의 구현 및 다른 모든 것들입니다 :
internal class Program : IWin32Window
{
...
}
IWin32Window
구현 :
public IntPtr Handle
{
get { return NativeMethods.GetConsoleWindow(); }
}
그것은 다음과 같은 클래스 사용
internal static class NativeMethods
{
[DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow();
}
이제 문제는 당신이 실제로 정적 메서드 인, Main
에 this
를 호출 할 수 있다는 것입니다을, 그래서이 이동 한 Main
에 있었다 어떤 Start
이라는 새로운 메서드와 모든 Main
이 수행하는 것은 Program
을 새로 만들고 Start
을 호출하는 것입니다.
private static void Main()
{
new Program().Start();
}
private void Start()
{
AppDomain.CurrentDomain.UnhandledException += CatchUnhandled;
throw new Exception();
}
결과는 물론 내 콘솔의 창을 소유자로 한 메시지 상자였습니다.
메시지 상자에이 방법을 사용하는 것은 당연히이 방법을 한 번 적용하는 것입니다.
간단히 대답은 : [DllImport ("kernel32.dll")] 내부 정적 extern IntPtr GetConsoleWindow(); –
- 전술
Process.MainWindowHandle
methodonly works for the process that started the console FindWindowByCaption
method는
여기이 할 수있는 강력한 방법 본질적으로 신뢰할 수 :
Console Win32 API에서 관련 기능
은 다음과 같습니다[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
static extern bool FreeConsole();
현재 프로세스가 부착 된 콘솔
- , 그냥
GetConsoleWindow()
그 즉시FreeConsole
로 분리,GetConsoleWindow
전화,AttachConsole
와 같은 잘 부착, 다른 프로세스에 첨부 된 콘솔 - 충분하다. 여분의주의를 들면
뿐만 아니라 콘솔 이벤트 당신이에 연결하고있는 작은 시간 프레임에서 일어나는 경우에 당신이 실수로 종료되지 않도록 연결하기 전에 콘솔 이벤트 핸들러를 등록 (및 분리 후 등록을 취소) 콘솔 :
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine,
bool Add);
delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
enum CtrlTypes : uint {
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
bool is_attached=false;
ConsoleCtrlDelegate ConsoleCtrlDelegateDetach = delegate(CtrlType) {
if (is_attached = !FreeConsole())
Trace.Error('FreeConsole on ' + CtrlType + ': ' + new Win32Exception());
return true;
};
뭔가를 읽고 현재의 프로세스를 변경하기는이 콘솔 프로세스가있는 경우는 현재 콘솔을 종료 피하기 위해 도우미 프로세스를 필요로하기 때문에,이 정말 추한 도착 (오히려 추한). 그럼에도 불구하고 추가 조사 결과 csrss
프로세스 또는 대상 프로세스에 주입 할 수있는 다른 방법이 없다는 것을 보여줍니다.
콘솔 대응 정보는 csrss.exe
(또는 Vista 이후 각 세션마다 하나씩)에 관리되고 있으므로 ReadProcessMemory
과 같이 검색 할 수 없습니다. 모든 csrss
노출은 CSRSS LPC API입니다. 전체 API 목록에는 관련 함수가 하나만 있습니다 (SrvGetConsoleWindow
). 그리고 PID를 허용하지는 않지만 an alternative implementation에 표시된 발신자 또는 해당 장치의 해체를 winsrv.dll
으로 결정합니다.
이것은 허용 된 대답이어야합니다. 이 작업을 수행하는 올바른 방법은 GetConsoleWindow입니다. 여기에있는 다른 답변 중 많은 부분은 단순한 구피입니다. –
IDE와 달리 콘솔에서 응용 프로그램을 실행할 때 응용 프로그램이 작동하지 않는 이유를 파악하는 데 시간을 낭비하지 않는 한 정답입니다. 이반 감사합니다. – WiredEarp
콘솔에 진단 도구를 스트리밍하고 콘솔에서 마우스 입력을 사용하지 않으려는 콘솔 응용 프로그램에서 GetConsoleWindow(), Process.GetCurrentProcess().MainWindowHandle, and FindWindowByCaption(IntPtr.Zero, Console.Title)
을 시도했습니다. 이들 각각은 0이 아닌 핸들을 반환했지만 SetConsoleMode에서 해당 핸들을 사용하려고하면 "잘못된 핸들"예외가 발생합니다. 마지막으로 STD_INPUT_HANDLE이 -10으로 정의 된 SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode | ENABLE_EXTENDED_FLAGS))
을 시도해 보았습니다. MS의 문서에 따르면 콘솔에 대한 핸들이 다시 할당 될 수 있으며이 솔루션에 만족스럽지 않거나 만족스럽지 않지만 지금까지는 빠른 편집 모드를 프로그래밍 방식으로 사용하지 않도록 설정할 수있는 유일한 방법입니다. GetStdHandle(STD_INPUT_HANDLE)
이 '3'을 반환하면 다른 호출은 프로그램이 실행될 때마다 달라지는 7 자리 값을 반환합니다.
- 1. 콘솔 입력에 쓰고 콘솔 핸들을 얻는 방법은 무엇입니까?
- 2. Win32 콘솔 응용 프로그램 대 CLR 콘솔 응용 프로그램
- 3. : 내 콘솔 응용 프로그램
- 4. QtWebkit : 콘솔 응용 프로그램
- 5. iOS의 상태 표시 줄에서 핸들을 얻는 방법
- 6. "서버 콘솔"을 얻는 방법
- 7. IOC 콘솔 응용 프로그램 용?
- 8. .NET 콘솔 응용 프로그램 configSections
- 9. 자바 콘솔 응용 프로그램 재시작
- 10. 콘솔 응용 프로그램 피자 조각
- 11. VB.Net 콘솔 응용 프로그램 스레딩
- 12. cmd와 같은 콘솔 응용 프로그램
- 13. C++ 콘솔 응용 프로그램 MVC
- 14. REPL 콘솔 응용 프로그램 서비스
- 15. 응용 프로그램 창의 커서가 올바르지 않습니다.
- 16. Grails 데이터 소스 핸들을 얻는 방법
- 17. 브러시, Win32 C++ 핸들을 얻는 방법
- 18. Compact Framework에서 MainMenu 객체의 핸들을 얻는 방법
- 19. 크기 조정 이벤트에서 핸들을 얻는 방법
- 20. facebook iframe 응용 프로그램 창의 크기를 조정하는 방법
- 21. 최소화 된 창의 RESTORED 경계를 얻는 방법?
- 22. 콘솔 유틸리티 응용 프로그램의 응용 프로그램 버전에 대한 방법
- 23. VS 2003 : 콘솔 응용 프로그램 .net remoting
- 24. WAR 응용 프로그램을 콘솔 응용 프로그램으로 변환하는 방법 (유니콘에 콘솔 응용 프로그램 사용)
- 25. 간단한 콘솔 Java를 사용하는 응용 프로그램
- 26. JBoss 응용 프로그램 서버의 상태를 얻는 방법
- 27. Mac에 설치된 응용 프로그램 목록을 얻는 방법
- 28. 안드로이드에서 응용 프로그램 권한 설정을 얻는 방법?
- 29. 내 응용 프로그램 디렉토리 이름을 얻는 방법
- 30. winforms에서 응용 프로그램 설정 경로를 얻는 방법?
이 기능을 사용 했습니까? 그냥 호기심, 왜냐하면 나는 몇 곳에서 이것을 사용할 수 있기 때문에 :) – Pwninstein
2-22 년 후에 다른 사람을 찾고; 예, 이것은 (나를 위해) 효과가있었습니다. –
이것은 프로세스가 콘솔을 시작한 경우에만 작동하는 것으로 보입니다. 다른 콘솔에서 실행하면 항상 0이됩니다. 다른 상황에서 findwindowbycaption을 사용해야 할 것 같습니다 (http://support.microsoft.com/kb/124103 참조). –