최근에 다단계 인증과 관련해서 Credential Provider를 확장해서 만들 일이 있어 급히 하나 만들어 봤다.
방법은 예전에 쓴 아래 글 참조.
>> 참조: Winlogon GINA/Credential Provider 커스터마이징
C++로 Credential Provider 기본 코드를 작성하고
다단계 인증의 세부 코드 및 UI는 쉽게 유지 보수가 가능한 C# DLL로 만들어
WinForm으로 WebBrowser를 임베딩하여 실행하는 방식으로 만들었다.
(C++에서 C# DLL을 호출하는 방법은 역시 위 참조 글(7, 8번)에 기록되어 있다.)
그런데, Windows 10 64비트 OS를 기준으로 만들었더니
Windows 7 64비트 OS에서는 정상 동작하지 않는 문제가 있어 하나하나 확인하고 수정해야 했다.
Windows 10에서는 정상 동작하나 Windows 7에서는 오류가 발생한 대표적인 문제들은,
1. Advice()와 UnAdvice() 함수 호출이 전혀 다른 점
Windows 10에서는 로그인 화면에서 ID/Password를 입력할 때 Advice() 및 UnAdvice()가 최초 한번씩만 호출되었는데 Windows 7에서는 매번 커서를 누를 때마다 Advice() 및 UnAdvice() 두 함수가 계속 반복 호출되었다. 그래서 해당 함수들 내에 만들어 두었던 외부 DLL 로딩/언로딩 처리 부분을 다른 곳으로 옮겨야 했다. 결과적으로는 옮긴 곳이 더 적절한 위치인 것 같아... 잘 옮겼다는 생각.
2. System.Windows.Forms.Timer가 동작하지 않는 점
Windows 10에서와 달리 Windows 7에서는 Credential Provider에서 실행시킨 C# WinForm에서 System.Windows.Forms.Timer의 Tick 이벤트가 전혀 발생하지 않았다. Single Thread(STA) 환경에서만 동작한다는 얘기들이 인터넷에 많은 것으로 보아 아마 Credential Provider 실행 환경은 Multi Thread 환경이기 때문에 그런 것 같은데, 그럼 왜 Windows 10에서는 정상 실행되었을까?
Windows 10의 System.Windows.Forms.Timer 설계에 변경이 생긴 것일까? MTA에서도 동작하도록?
>> 참고: https://stackoverflow.com/questions/18327567/system-windows-forms-timer-not-firing
3. WebBrowser 컨트롤의 Navigate()가 먹통이 되는 점
Windows 10에서는 아무 문제없이 잘 됐는데 Windows 7에서는 WebBrowser 네비게이션이 아예 동작하지 않아서 도대체 무엇이 문제인지 찾아 봤더니 Windows 7 64비트 OS의 DEP(Data Execution Prevention) 관련 문제라는 글들이 많이 보였고, AnyCPU가 아닌 32비트로 컴파일하면 해결된다는 얘기도 있었지만 그럴 수 없는 환경이었기 때문에 시도해보진 못했다. 64비트에서도 완벽하게 동작하는 방식이어야 했기 때문이다.
대신, 아예 WebBrowser 컨트롤로 웹 화면을 보여주던 방식을 없애 버리고, 별도 Web API를 호출하여 원하는 값(이미지)을 얻어와 화면상에 이미지로 표현하는 방식으로 대수술을 해야 했다. (말은 쉽지... 털썩.)
4. System.Timers.Timer에서 WinForm의 InvokeRequired가 항상 true인 점
Multithread 환경이지만 매초마다 ProgressBar를 움직이게 하기 위해서는 어쨌든 Timer를 사용해야 했기 때문에 System.Windows.Forms.Timer 대신 궁여지책으로 사용한 것이 System.Timers.Timer였는데, 희한하게도 ProgressBar를 업데이트하기 위해 InvokeRequired를 체크하면 늘 항상 true로 결과가 리턴되었다. 어째서지? 하면서 System.Threading.Timer로 바꿔보기도 하고 public method로 바꾸어 외부에서 호출해 보기도 하는 등 며칠간 별의 별 짓을 다 해봤지만 해결이 안되었다.
결론은, InvokeRequired를 체크하지 않고 그냥 실행하면 되는 것이었다.
>> 참고: https://www.codeproject.com/Questions/616034/how-to-use-System-Timers-Timer-to-control-a-progre
헐... 한 마디로 삽질... 며칠 간 삽질만 했다. 미친 척 하고 그냥 한번 실행해 보면 됐을텐데...
그런데, 아직도 왜 그냥 호출하면 되는지 당최 이유를 모르겠다.
InvokeRequired 상태니까 그냥은 정상 업데이트 동작이 안돼야 하는데 말이다. 대체 왜 되는 걸까?
'Tech: > 일반·기타' 카테고리의 다른 글
Windows 10 - 1703 버전 (0) | 2017.07.28 |
---|---|
Angular2를 파보다가 멘붕 (0) | 2017.07.27 |
Windows 폴더 숨기기 (0) | 2017.03.08 |
Windows 10 사용자 정보 추적 개인정보 수집 차단 (0) | 2017.03.08 |
크롬 업데이트(2016.08) 후 스크립트 오류(with 문) (0) | 2016.08.12 |