System.Diagnostics.Process는 내가 아는 한 문자 만 허용하는 StandardInput이라는 StreamWriter를 노출합니다.문자 대신 키를 프로세스에 보내는 방법은 무엇입니까?
그러나 키 스트로크도 보내야하며 일부 키 입력은 문자에 잘 맵핑되지 않습니다.
어떻게해야합니까?
System.Diagnostics.Process는 내가 아는 한 문자 만 허용하는 StandardInput이라는 StreamWriter를 노출합니다.문자 대신 키를 프로세스에 보내는 방법은 무엇입니까?
그러나 키 스트로크도 보내야하며 일부 키 입력은 문자에 잘 맵핑되지 않습니다.
어떻게해야합니까?
되어야 백 스페이스 Ctrl + C를 가압
는 제어 신호에 스트림. 콘솔 프로세스에는 이미 알고있는 것처럼 StandardInput으로 제어 할 수있는 기본 입력 스트림이 있습니다. 그러나 Ctrl 키 C 및 Ctrl 키 틈이 스트림을 통해 프로세스로 전송 문자 아니지만, 대신에 그들이 제어 신호는 프로세스가 등록 신호 처리기를 사용하여, CTRL+C and CTRL+BREAK Signals 참조받는 대신 같습니다
기본적는, 콘솔 창에 키보드 포커스가있는 경우 CTRL + C 또는 CTRL + BREAK는 (SIGINT 또는 SIGBREAK) 신호로 처리되며 키보드 입력으로 처리되지 않습니다.
GenerateConsoleCtrlEvent
을 사용하고
CTRL_C_EVENT
또는
CTRL_BREAK_EVENT
중 하나를 보낼 수있는 프로세스에 가짜 신호를 보낼 수 있습니다. 이 API에는 .Net에 해당하는 것이 없으므로 PInvoke해야합니다.
const int CTRL_C_EVENT = 0;
const int CTRL_BREAK_EVENT = 1;
[DllImport("kernel32.dll")]
static extern bool GenerateConsoleCtrlEvent(
uint dwCtrlEvent,
uint dwProcessGroupId);
http : // www. google.com/codesearch/p?hl=ko#ncfzeHH4QLA/pubs/consoledotnet/consoledotnet.zip%7CYrqh4ujA6zA/ConsoleDotNet/WinCon.cs –
화면 녹화의 FFmpeg 프로세스를 사용하고 있습니다. 이게 저에게 효과가 있습니까? 사실 FFmpeg – Ahmad
당신을 위해 단지 일을 할 수 시뮬레이터 Codeplex에 여기 입력이있다 : 당신은 단순히 함수 정의를 포함해야 .NET
은에서를 사용합니다. 나는 샘플 코드에 일하고 입력 시뮬레이터 레무스에서 제공하는 링크에서 발견 된 것과 유사하다 마음에, 곧 다시 여기 곰을 게시 할 예정입니다 ...편집 : 나는이 있음을 발견했다 이것에 대한 제한은, 당신은 분명히 전형적인 System.Windows.Forms.SendKeys.Send
방법으로 벗어날 수 있습니다, 그것은 효과적으로 작동합니다!
하지만, 과정은
, 그것은 창을 찾는 문제입니다, 'SetForegroundWindow'PInvoke를 통해 활성 설정하고 (매우 잘 작동 않는 시퀀스를 프로세스에 Ctrl 키 + 브레이크 신호를 보내 ^{BREAK}
을 보내 특히 프로세스가 명령 행 프로그램/배치 파일 인 경우).이 사실 나는 매우 당황 스럽네요으로 ... : 다음은이를 정확하게 수행하고 내가 입증이에 몇 가지 코드를 붙여 아직 ...에서 SendKeys를 반영 CodeProject에 대한 기사 ....
편집 # 2입니다
FindWindow
API 호출에서 약간의 부정 행위를했는데, 그 이유는 내가 창 제목이 무엇인지 알았고 어떻게 든 포 그라운드로 가져 와서 InputSimulator를 사용하여 키 입력을 보내거나 전통적인 평범한 구 SendKeys
기능 ... 내가 Thread.Sleep
을 가지고 있었던 이유는 "액티브 전경 윈도우"의 키보드 대기열에 눌려 지도록 키 스트로크가 보내지는 것을 보장하는 것입니다. 그 외에도 "숨겨져 있습니다"public partial class Form1 : Form
{
private TestNetStat netStat = new TestNetStat();
public Form1()
{
InitializeComponent();
using (BackgroundWorker bgWorker = new BackgroundWorker())
{
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
bgWorker.RunWorkerAsync();
}
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("BGWORKER ENDED!");
}
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
netStat.Run();
}
void btnPost_Click(object sender, EventArgs e)
{
netStat.PostCtrlC();
System.Diagnostics.Debug.WriteLine(string.Format("[{0}] - {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), this.netStat.OutputData.Replace(Environment.NewLine, "")));
}
}
public class TestNetStat
{
private StringBuilder sbRedirectedOutput = new StringBuilder();
//
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
public static extern int SetForegroundWindow(IntPtr hwnd);
public string OutputData
{
get { return this.sbRedirectedOutput.ToString(); }
}
public void PostCtrlC()
{
IntPtr ptr = FindWindow(null, @"C:\Windows\System32\netstat.exe");
if (ptr != null)
{
SetForegroundWindow(ptr);
Thread.Sleep(1000);
WindowsInput.InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.CANCEL);
// SendKeys.Send("^{BREAK}");
Thread.Sleep(1000);
}
}
public void Run()
{
System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo();
ps.FileName = "netstat";
ps.ErrorDialog = false;
ps.Arguments = "-e 5";
ps.CreateNoWindow = true;
ps.UseShellExecute = false;
ps.RedirectStandardOutput = true;
ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
{
proc.StartInfo = ps;
proc.EnableRaisingEvents = true;
proc.Exited += new EventHandler(proc_Exited);
proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
}
void proc_Exited(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended");
}
void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (e.Data != null)
{
this.sbRedirectedOutput.Append(e.Data + Environment.NewLine);
System.Diagnostics.Debug.WriteLine("proc_OutputDataReceived: Data: " + e.Data);
}
}
}
Nitpicky을, 나는 netStat
가 'BackgroundWorker에'스레드를 실행하는 것을 알고, 내가 직접 메인 GUI 스레드에서 'PostCtrlC'방법을 호출 ... 이것은 같은 현학적이다 proof-of-concept 코드를 제공하지만 스레드 안전을 위해 'ISynchronizeInvoke'를 구현해야한다는 것을 보여줍니다. 그렇다고해서 실제로 작동합니다.
을 사용하여 화면 녹화의 프로세스 시작을 중지하고 싶지만 netstat를 사용하는 여러 프로세스를 실행중인 경우.exe 인 경우 PostCtrlC()에 모두 영향을 미칩니 까? SessionId 프로세스를 알면 같은 일을 할 수있는 방법이 있습니까? – Constantin
@ Constantine 코드는 netstat.exe를 실행하는 하나의 창만 대상으로합니다. [EnumWindows] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85) .aspx)를 사용하여 콜백 함수 [EnumWindowsProc] (http : //msdn.microsoft.com/en-us/library/windows/desktop/ms633498(v=vs.85).aspx) 핸들을 가져 와서 해당 핸들의 제목에 netstat.exe가 있는지 확인하십시오. 제목 ... 그 발견되면 포어 그라운드로 가져 와서 위의 개념 증명 코드와 같이 그것을 "압축"하십시오. – t0mm13b
예를 들어 어떤 키 스트로크입니까? –
@Rick 백 스페이스, Ctrl + C –
이것은 유닉스 파이프 추상화의 궁극적 인 누수입니다. 리디렉션은 문자 스트림을 통해 이루어지며 비 타이핑 키 스트로크를 시뮬레이션 할 수 없습니다. –