티스토리 뷰
목차
예전에 회사에서 만들었던 C# 비동기 테스트 소스입니다. cmd.exe 직접 제어하여 콘솔에 명령어 날리고 응답 값을 바당 뿌려주는 소스인데요. 아래에도 소개하겠지만, static async Task<string> DoSignAsync() 함수를 꾸며서 원하는 대로 수정하여 사용할 수 있습니다.
큰 흐름상, C# ProcessStartInfo 객체를 이용해 프로세스를 제어하고, async DoAction() 함수로 비동기 함수 호출, 종료 등 큰 흐름을 잡습니다. 세부적인 task 동작은 위에서 언급한 DoSignAsync 함수에서 담당합니다.
◆ 전체 C# 소스 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | namespace ProcessAsyncExam { class Program { static private string PROCESS_NAME_CMD = "cmd.exe"; static ProcessStartInfo psi = null; static Process proc = null; static void Main(string[] args) { psi = new ProcessStartInfo(); psi.UseShellExecute = false; psi.CreateNoWindow = false; psi.RedirectStandardOutput = true; psi.RedirectStandardInput = true; psi.RedirectStandardError = true; proc = new Process(); proc.EnableRaisingEvents = true; proc.ErrorDataReceived += (object sending_process, DataReceivedEventArgs e) => { if (e.Data != null) { Console.WriteLine(e.Data.ToString()); } }; proc.OutputDataReceived += (object sending_process, DataReceivedEventArgs e) => { if (e.Data != null) { Console.WriteLine(e.Data.ToString()); } }; DoAction(); Console.ReadLine(); } static async void DoAction() { psi.FileName = PROCESS_NAME_CMD; psi.WorkingDirectory = "C:\\"; proc.StartInfo = psi; proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); await DoSignAsync(); proc.CancelOutputRead(); proc.CancelErrorRead(); proc.Close(); } static async Task<string> DoSignAsync() { string console_cmd = "dir"; proc.StandardInput.Write(console_cmd + Environment.NewLine); proc.StandardInput.Flush(); await Task.Delay(20); for (int j = 0; j < 10; j++) { await Task.Delay(1000); // 비동기 작업이라 결과가 언제 날아올지 몰라 임의로 대기 시간 할당 Console.WriteLine(j); } await Task.Delay(1000); proc.StandardInput.Close(); return null; } } } | cs |
하나씩 살펴볼게요.
◆ ProcessStartInfo 객체
cmd.exe 실행하기 위한 객체입니다. C# ProcessStartInfo를 통해 제어할 수 있어요.
44~45번 라인 : PROCESS_NAME_CMD (cmd.exe) 커맨드창의 시작 위치를 C:\로 설정합니다.
◆ Process 객체
이 소스에서는 cmd.exe를 가리킨다고 보면 되겠습니다. EnableRaisingEvents 값을 true로 바꿔 이벤트 발생을 활성화합니다.
28~34번 라인 : 프로세스 제어 과정에서 발생한 에러를 출력합니다.
36~42번 라인 : 커맨드창에 출력되는 메시지를 비주얼스튜디오 콘솔에 출력합니다. 예를 들어, 커맨드창에 A를 입력하면 B라는 응답 값이 나옵니다. 여기서 B를 콘솔에 찍어주는 것이죠.
◆ DoAction 함수
프로시저 설정, 시작, 비동기 읽기, 비동기 에러 출력, 비동기 함수 실행, 프로시저 종료입니다. 위에서부터 순서대로 읽는 것 그대로입니다.
BeginOutputReadLine 함수 <-> CanCelOutputRead 함수는 한 쌍으로 사용합니다. 비동기 읽기를 실행만 해놓고 cancel 함수 호출 안 하면 프로세스 점유 상태가 끝나지 않습니다.
◆ Task<string> DoSignAsync 함수
타스크 string 중 string이 실제 cmd.exe 콘솔창에 입력되는 메시지입니다. 사용자 입력 부분이죠. input data 입니다. output은 29번 라인에 설정해 두어서 이 함수에 별도로 구성할 필요는 없어요.
이 함수는 제가 테스트하려고 만든 소스 중 일부입니다. 민감한 건 다 삭제하고 껍데기만 남아 있네요. 커맨드 창 프로세스를 제어하실 때, 이 함수를 적절히 꾸미면 됩니다.
이 정도로 C# 비동기 프로세스 제어 소스 예제 소개를 마치겠습니다. 이해가 안 되는 부분이 있다면 댓글로 남겨주세요. 최대한 자세히 알려드리겠습니다.
관련 글
▷ C# 비동기 Async, 소켓 서버, 함수 소스 (Socket network)
▷ C# TASK 7가지 사용법, C# 스레드는 이제 그만
▷ C# 외부 프로그램 (프로세스) 실행하기 (Process Start)
ⓒ written by vicddory