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の奇妙な動作のために私はそれに標準入力を渡すことができず、標準出力を読むこともできません。それをしようとすると、私のアプリはwritelineコマンドでブロックされます。私はstdoutの中に "Password:"という言葉を見たかったでしょう。私はいくつかの非同期の例とマルチスレッドを試みましたが、そのようなものではありません。標準出力バッファは常に空です。私はそれが書かれているstdoutに書かれていない場合、私は "パスワード:"見ているこのテキストは何ですか?

これは私が使用するコードです。 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で書かれた古いプログラムがそのように動作すると不満を寄せている記事を読んでいました。私はそれをよりきれいにやりたかったのですが、これは私が思いついたものです。基本的にキーストロークをコンソールウィンドウに送ります。タスクスケジューラでプロセスを開始していて、ビジュアルウィンドウが作成されていないためにうまく動作しているかどうかはわかりませんでしたが、正常に動作しているようです。

私は別のスレッドでの処理を開始します。

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(); 

その後、私はすべてのウィンドウを列挙:

EnumWindows(EnumTheWindows, IntPtr.Zero); 

その後、私は私のプロセスのウィンドウを探し、そこに目的のキーストロークを送信。その間の睡眠は働かないと必要です。送信しているサンプルのパスワードは「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; 
    } 

これは誰かが時間を節約するのに役立ちます。

関連する問題