none
윈도우7에선 GenerateConsoleCtrlEvent가 작동하지 않는것 같은데 어떻게 해야 할까요? Ctrl+c로 ffmpeg을 종료시키는 다른방법 있을까요? RRS feed

  • 질문

  • 안녕하세요.

    비주얼 베이직으로 FFmpeg기반 (API호출이 아닌 단순히 EXE파일을 연동 합니다) 인코더를 제작중인데요 (.Net Framework4)

    인코딩 중지할때 단순히 process kill()로 중지하는 간단한 방법이 있지만

    mp4 포맷 인코딩시 프로세스를 중단시키면 제대로 마무리가 되지 않아서 껍데기만 남은 재생불가능한 파일이 생성되고

    Ctrl+C나 q를 누르면 제대로 마무리가 되면서 인코딩 도중 중단 되더라도 생성된 파일을 재생 해볼수 있습니다

    그래서 process kill하는 방법보다는 ctrl+c나 q로 중지하는 방법으로 하기위해

            AttachConsole(CUInt(p.Id))
            GenerateConsoleCtrlEvent(CTRL_C_EVENT, CUInt(p.Id))
            FreeConsole()

    이런식으로 ctrl+c 이벤트를 날려서 종료하도록 만들었습니다

    그런데 윈도우8.1이나 10에선 정상 작동을 하는데 7에서는 아무런 반응이 없네요 (Exception도 안뜹니다)

    원인을 파악해보려던 중 process  tree구조를 보니 윈7과 8.1 차이점이 있더라고요

    윈도우 8.1의 process tree는

    비베로 제작한 exe파일.exe

      ㄴ cmd.exe

         ㄴ conhost.exe

             ffmpeg.exe

    이런식으로 tree를 이루고 있는데

    윈도우7의 process tree는

    비베로 제작한 exe파일.exe 

       ㄴ cmd.exe

           ㄴ ffmpeg.exe

    그리고 이와 별도로 conhost.exe는 crss.exe 밑에 tree를 이루고 있었습니다.

    crss.exe

       ㄴconhost.exe

    지금 추측으론 이것 때문에 이벤트가 전달되지 않는게 아닌가 하는 생각을 하고 있습니다

    console 이벤트는 conhost를 통해 주고받는다고 알고 있는데 conhost까지 전달이 안되거나 conhost에서 ffmpeg까지 전달을

    안해주는게 아닌가 하는 생각이 듭니다. 

    Ctrl+c나 q로 ffmpeg를 종료 하는 방법이 없을까요?

    GenerateConsoleCtrlEvent을 통한 방법도 좋고 다른방법 이라도 좋습니다.

    sendkeys로 ctrl+c 하는 방법도 봤지만 작동하지 않았습니다

    그리고 ffmpeg를 실행할땐 왠만해선 cmd를 통해서 하려고 합니다.

    아래 ffmpeg 실행방식은 소스는 답변해주시는데 될것 같아 올립니다.

    ffmpeg 실행은 BackgroundWorker1와 process StartInfo로 실행합니다 (ffmpeg cmd 창을 띄우지 않습니다)

    (FFPARAM에 FFmpeg 실행파일명과 parameter가 정의되어 있습니다)

     With p.StartInfo
                .Arguments = " /c title Encoder & " + FFPARAM
                .FileName = "cmd"
    
                .UseShellExecute = False
                .RedirectStandardError = True
                .RedirectStandardInput = True
                .CreateNoWindow = True
    
    
            End With
            p.Start()









    • 편집됨 kgp701 2015년 7월 8일 수요일 오전 6:02
    2015년 7월 8일 수요일 오전 4:46

답변

  • 외부 exe를 실행시킬때에도 SetConsoleMode() 함수를 호출하는 것이 도움이 될지는 모르겠네요. 보통은 콘솔 프로그램 내에서  SetConsoleMode() 함수에 ENABLE_PROCESSED_INPUT option flag를 사용할 듯한데요.

    일단 다음 자료들을 참고하세요.

    http://stackoverflow.com/questions/18564601/how-to-get-generateconsolectrlevent-to-work-with-cmd-exe
    How to get GenerateConsoleCtrlEvent to work with cmd.exe

    on Windows 7, pressing Ctrl-C sends messages that are read by conhost.exe which communicates with csrss.exe, which calls NtCreateThreadEx with kernel32!CtrlRoutine.

    The SetConsoleMode() winapi function, ENABLE_PROCESSED_INPUT option flag is relevant. It allows a program to specify whether it wants to see Ctrl+C itself or leave it up to the system to handle it. This flag is definitely off for cmd.exe. Since pressing Ctrl+C doesn't terminate it.

    http://www.codeproject.com/Articles/2357/Console-Event-Handling
    Console Event Handling

    • 답변으로 표시됨 SMPark82 2015년 8월 13일 목요일 오전 1:16
    2015년 7월 29일 수요일 오후 8:34