2017-09-17 4 views
-1

흥미로운 상황이 있습니다. 명령 줄에서 프로그램을 실행하려고하고 있는데 프로그램 적으로 입력을 리디렉션 할 수 없습니다. 실행중인 실행 파일이 호출됩니다. Spideroakone.exe. 이 실행 파일은 암호를 묻습니다. 암호를 입력하면 암호가 "asd"라고 말할 수 있으며 일반 텍스트로 무엇을 입력하는지 실제로 볼 수 있습니다.C# 리디렉션 입력 콘솔 응용 프로그램이 작동하지 않습니다.

cmd /c Spideroakone.exe 

가 다시 내가 암호를 요청하고 동일한 참조 : 그와 같은 실행 파일을 실행하면

'asd' is not recognized as an internal or external command ... 

: 나는 오류 메시지가 표시됩니다. 그럼 나는 asd를 타이프한다. 하지만 입력 한 내용을 볼 수없고 암호가 작동하고 오류가 없습니다.

이제는 Spideroak.exe을 실행하고 표준 입력에 암호를 전달하는 앱을 작성하고 싶습니다. 그러나 Spideroak의 이상한 행동으로 인해 표준 입력을 전달할 수 없으며 표준 출력을 읽을 수도 없습니다. 그것을하려고 할 때 내 app 블록 writeline 명령을 차단합니다. 나는 stdout에서 "Password :"라는 단어를 보았을 것이다. 비동기식 예제와 멀티 스레딩을 시도했지만 그 중 일부는 작동하지 않습니다. 표준 출력 버퍼는 항상 비어 있습니다. 나는 그것이 쓰여지는 stdout에 쓰여지지 않는다면 "Password :"라는 글자가 무엇인지 궁금합니다.

이것은 내가 사용하는 코드입니다. ReadToEnd() 행의 어떤 블록. 이 정확한 코드는 내가 그래서 이것은 제가 실행하려고 실행 파일이 이상한 방식으로 작성되어 생각하게 만든 콘솔 응용 프로그램과 잘 작동하지만 명령 줄 창에서 그것을 잘 작동합니다 :

Process myProcess = new Process(); 

myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe"; 
myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless"; 
myProcess.StartInfo.UseShellExecute = false; 
myProcess.StartInfo.RedirectStandardOutput = true; 
myProcess.StartInfo.RedirectStandardInput = true; 

myProcess.Start(); 

string s = myProcess.StandardOutput.ReadToEnd(); 
myProcess.WaitForExit(); 

이가 정확한 디버그 윈도우의 스크린 샷 및 라인이 블록에 : ​​

:

이 내가 명령 줄 창에 표시되는 내용입니다

+0

질문을 편집하고 [mcve] (https://stackoverflow.com/help/mcve)를 제공하는 코드를 추가하십시오. –

+0

현재 열려있는 cmd의 출력을 파일로 리디렉션하는 방법을 알고있는 사람도 있습니까? . 내 말은 입력 할 때 asdf 명령 프롬프트에 메시지가 나타납니다. '... 내부 또는 외부 명령으로 인식되지 않습니다 ...' 이 파일을보고 싶습니다. 어떻게 그 일을합니까? 내 문제와 관련이있을 수 있습니다. –

+0

그게 아니야. 오류 출력이 표준 출력과 다르기 때문입니다. –

답변

0

아무도 대답하지 못했고 그 말은 대답을 찾았습니다. 나는 stdout과 stdin이 작동하지 않는 정확한 이유를 찾지 못했지만 누군가가 getch()를 사용하여 C로 작성된 오래된 프로그램이 그런 식으로 행동한다고 ​​불평하는 기사를 읽었습니다. 나는 좀 더 예쁜 방식으로하고 싶었지만 이것이 내가 생각해 낸 것입니다. 기본적으로 키 스트로크를 콘솔 창에 보냅니다. 작업 스케줄러에서 프로세스를 시작하고 시각적 창을 만들지 않아 제대로 작동하는지 알 수 없었습니다.

나는 별도의 스레드에서 프로세스를 시작 : 내 프로세스의 창을 찾아서 그것을 원하는 키 스트로크를 보내 다음

EnumWindows(EnumTheWindows, IntPtr.Zero); 

:

new Thread(() => 
     { 
     Process myProcess = new Process(); 

     myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe"; 
     myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless"; 
     myProcess.StartInfo.UseShellExecute = false; 
     myProcess.Start(); 

     myProcess.WaitForExit(); 
     }).Start(); 

가 그럼 난 모든 창을 열거 . 그 사이의 수면은 작동하지 않으면 필요합니다. 보내시는 샘플 비밀번호는 'asd'입니다.

private static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam) 
    { 
     uint pidCurWindow; 
     uint CurWindowThreadId = GetWindowThreadProcessId(hWnd, out pidCurWindow); 
     int CurrentPID = System.Diagnostics.Process.GetCurrentProcess().Id; 

     if (pidCurWindow == CurrentPID) 
     { 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('a'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('s'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('d'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1); 
      Thread.Sleep(50); 
     } 
     return true; 
    } 

시간을 절약하는 데 도움이되기를 바랍니다.