고양국제고/셰어텍

[셰어텍] 7. '.NET 네이티브 툴체인' 버그 및 타겟 변경

카루-R 2021. 10. 14. 18:00
반응형

환영합니다, Rolling Ress의 카루입니다.

Co-net에 문제가 생겼습니다. 버전 0.1.3에서 일어났던 일인데, 스토어에서 앱을 다운받고 실행하면 아래와 같은 메시지가 나옵니다.

이것도 모자라서 그 뒤에 에러가 하나 더 뜹니다.

이건 뭐 큰 문제는 아니에요. 원래 GGHS Time Table도 그렇고, GGHS Todo도 그렇고 문제가 생기면 저에게 자동으로 오류를 보고할 수 있도록 프로그래밍을 해뒀습니다. 모종의 이유로 지금 메일이 보내지지 않아서 문제가 생기는 거니까, 프로그램 문제는 아니에요. 그런데, 문제는 저 첫번째 오류입니다.


계속 디버그를 하면서 오류를 잡았습니다. 뭐가 문제일까? 결론은 좀 허무했지만... 단서들을 순서대로 써보겠습니다.

1. 내 PC에서는 정상적으로 실행이 된다. 그런데 다른 PC에서는 안 된다.

제 데스크탑, 그러니까 개발을 했던 컴퓨터에서는 멀쩡하게 잘 돌아갔습니다. 그런데 스토어에서 다운받은 프로그램은 이상하게 저게 계속 뜨더라고요. 그래서 첫 번째 단서는 "스토어에 올라가는 앱 자체에 문제가 있다"라는 거였습니다.

2. Debug 모드에서는 정상적으로 동작한다. Release에서 문제가 생긴다.

문제의 핵심. Debug에서는 멀쩡합니다. 그런데 Release 모드에서 대체 무슨 일이 있던 건지 유독 오류가 나더라고요. 분명히 Debug/Release 차이인데, 그럼 여기서 두 번째 단서를 얻을 수 있습니다. "컴파일러가 최적화 작업을 하면서 멀쩡한 걸 건드렸다."

3. 문제가 생기는 부분의 코드는 로그인 페이지를 Load할 때이다.

이것도 거의 확실했습니다. 중단점을 걸고 디버깅을 해보면 계속 똑같은 부분에서 오류가 났거든요.

// App.xaml.cs: ShareTechUWP.App.OnLaunched(LaunchActivatedEventArgs e) 
rootFrame.Navigate(typeof(LoginPage), e.Arguments);

근데 뭐... 이게 오류가 생길 만한 구문은 아닙니다. MainPage로 바꾸면 멀쩡한데? 글쎄요. 그 말은 LoginPage에서 뭔가 문제가 있었다는 얘기겠죠. 특히, ctor() 얘기가 나오는 걸로 보아선 생성자 쪽에 문제가 있는 겁니다. 로드 자체가 안 된다는 거겠죠.

4. '.NET Native tool chain'과 직접적인 연관이 있다.

디버그 모드에서는 기본적으로 닷넷 네이티브 툴체인을 사용하지 않습니다. 그런데, 릴리즈 모드에서는 이걸 사용하죠. .NET 네이티브 도구 체인이 뭐냐? 쉽게 말해서 .NET으로 짠 프로그램을 그냥 바로 기계어로 번역하는 겁니다. 네이티브 언어처럼 말이죠. 여기서 문제가 생긴 겁니다.

릴리즈 모드에서 저걸 사용하지 않아도 됩니다. 근데 그게 근본적인 해결책은 아니죠. 좀 삽질을 하다가, 원인을 몇 가지 더 찾았습니다.

5. 프로그램에서 동적으로 읽어오는 부분에서 문제가 발생한다.

이게 키포인트입니다. 릴리즈 모드에서는 저 닷넷 네이티브 툴체인 때문에 기계어로 바로 번역한다고 했죠. 이 과정에서 외부 어셈블리를 따로 지정하지 않으면 실제 실행될 때 참조가 불가능해 오류를 뿜어댑니다. 그럼 저도 똑같은 부분에서 문제가 생겼다는 얘긴데, 외부 어셈블리? 글쎄요. 딱히 추가한 게 없습니다. 그런데 생각해보니까 문제가 멀리 있지 않더라고요.

지난번에 보여드렸던 이 XML 파일. 이게 문제가 있었던 겁니다. 여기를 읽어오는 코드를 봅시다.

private string connectionString = ConfigurationManager 
    .ConnectionStrings["ConetUsers"].ConnectionString;

클래스 내부 인스턴스입니다. 그런데, ConfigurationManager...맞아요. 오류 메시지에 저게 있었죠. 이게 문제였습니다. 그래서 해결을 어떻게 하느냐? 미리 알려줘야지요. 얘는 런타임에 사용할 녀석이니, 꼭 동적으로 읽을 준비를 하라고.

<!-- Default.rd.xaml: Directives/Application --> 
<Type Name="System.Configuration.ClientConfigurationHost" Dynamic="Required All"/> 
<Type Name="System.Configuration.AppSettingsSection" Dynamic="Required All"/>

Default.rd.xaml 파일에 해당 내용을 추가해줍니다. 그냥 ConfigurationManager을 Required All이라고 써도 되지만... 그러면 앱 용량이 커져요. KISS(Keep It Simple, Stupid) 잊지 말자고요. 꼭 필요한 것만.

 

타겟 플랫폼 변경

원래 Conet은 윈도우 10 1803을 최소 버전으로 잡고, 윈도우 10 2004를 메인 버전으로 잡았습니다. 그런데 윈도우 10 1803은 CornerRaidus 옵션을 주지 않아요. 정의되지 않은 동작이 나올 수도 있고, 프로그램에 문제가 생길 수도 있습니다. 어쩔 수 없이 최소 버전을 올려야 하는데, 혹시나 고객들이 해당 버전을 많이 사용한다면 이 역시도 좋은 선택은 아니겠죠.

https://reports.adduplex.com/#/r/2021-09

 

AdDuplex Windows Device Statistics reports

 

reports.adduplex.com

위 사이트에 들어가보면 윈도우 10/11의 버전별 점유율을 확인할 수 있습니다.

의외로 업데이트 속도가 빠릅니다. 21H1, 못해도 20H2 버전을 대다수의 사람들이 사용하고 있네요. 1709, 1803이랑 1809는 아예 묶여버렸습니다. 다 해봤자 3.5% 밖에 안 된다는 얘기네요. 네, 버립시다. 필요 없어요.

이렇게 타겟 플랫폼 버전을 올렸습니다.

오늘도...커밋푸시를 합니다...

반응형