티스토리 뷰

반응형


오랜만에 포스트를 작성하네요. 음..변명을 하자면.. 챗봇 공부를 하고 있는 중이였는데 Build 2018 동영상이 나와서 그것 좀 보다가..끝나고 나니..뭘해야할지..막막


사실 Windows ML을 하려고 했으나, 머신 러닝을 위해서는 파이선을 공부해야 한다고 해서 한 몇일 고민하다가.. 일단 파이선 공부는 뒤로 미루고, Build에서 발표된 새로운 UWP에 기능에 대해서 집중하기로 마음을 먹고.. 마음의 위안을 삼은체 탱자 탱자 하다가.. 오늘에서야 ...ㅋㅋㅋ



하지만, 오늘 대박 소식을 전하려고 합니다. 그동안 UWP의 숙원 사업(?) 중에 하나가 사용자의 허가를 받지 않은 로컬 폴더와 파일의 목록을 조회하고, 열어서 가지고 오는 것이 있었습니다.


이 부분이 않되어서 참 많은 어려움이 있었죠..하지만, 이번 Build에서 드디어 추가되었습니다~ 와~~~ 그러면 자세히 알아 보도록 하겠습니다.



1. 참고

https://docs.microsoft.com/en-us/windows/uwp/files/file-access-permissions

https://github.com/Microsoft/AppModelSamples



2. BroadFileSystemAccess


이 녀석이 그 녀석입니다. 사용자의 허가(앱을 설치할 때)를 받으면 그 이후 부터는 폴더와 파일에 접근할 때 별도의 허가 없이도 가능합니다. 하지만, 이 녀석을 사용하기 위해서는 선행 조건이 있습니다.


UWP 앱 Target, Min 버전이 17134이여야 합니다.

또한, Windows 10 버전도 1803 버전이여야 합니다.

* 물론 Visual Studio 최신 버전이 필요하고, Windows SDK도 최신 버전이 필요합니다.

이 두가지 조건에 만족한다면, 바로 사용이 가능하며, 추가로 약간 귀찮은 작업을 해줘야 합니다.


Capability의 기능이기 때문에 Package.appxmanifest에 정의를 해줘야 하는데...

GUI 화면에서는 이 녀석을 찾을 수가 없습니다. (현재는.. 추후 추가될 것이라고 생각됩니다만..) 그래서, Package.appxmanifest 파일을 xaml editer로 열어서 수동 편집해 주어야 합니다.


<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp uap5 rescap">


...


  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="broadFileSystemAccess" />
  </Capabilities>




3. C:/ 폴더와 서브 폴더 목록을 가지고와 볼까요?


var rootFolder = await StorageFolder.GetFolderFromPathAsync(@"c:\");


이렇게 코딩하면 바로 c:/ 루트 폴더를 가지고 올 수 있습니다. 아무것도 묻거나 따지지 않습니다~ 여기가 바로 신세계입니다~ 


서브 폴더는 어떻게 가지고 오냐구요?

그건 이전과 동일하게, GetFoldersAsync()를 이용하면 됩니다.


        private async void GetSubDirectories(StorageFolder folder, TreeViewNode folderNode, int depth = 0)
        {
            try
            {
                if (depth > 1) return;
                var subDirs = await folder.GetFoldersAsync();
                if (subDirs.Any() == false || folderNode.Children.Any()) return;
                foreach (var subDir in subDirs)
                {
                    var subDirNode = new TreeViewNode
                    {
                        Content = new DirectoryModel
                        {
                            Name = subDir.Name,
                            Path = subDir.Path,
                            HasSubDirectory = false
                        },
                    };
                    GetSubDirectories(subDir, subDirNode,depth + 1);
                    folderNode.Children.Add(subDirNode);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }



4. WPF 프로그램을 UWP로 대체하는 날이 얼마 남지 않은 듯 합니다.


다만, 걱정은 우리나라 WPF 개발 시장과 개발자의 인식이 좀.. 거시기 하다는.. 흑흑..

왜 아직도 윈폼으로 개발하고 있나요..엉엉(물론 지금 제가 진행하는 프로젝트도 WPF 개발자를 구하지 못해서 방황하는 중이지만..) 그래도 이제는 WPF 더 나아가서 UWP 프로젝트가 마니 생기기를..


당분간 새로 추가된 기능들을 아래 소스 폴더에 정리할 예정입니다.



5. 소스


https://github.com/kaki104/UWP_17134



PS. 27일날 갑자기 방문자수가 500을 넘게 찍었던데 무슨일이 있었떤 거죠??



6. 질문 주신 내용에 대한 소스 추가 합니다.


DownloadsFolder.CreateFileAsync
DownloadsFolder.CreateFolderAsync

를 사용하면 파일 생성은 가능하지만 이미 생성된 파일이나 폴더가 있을 경우 get 할 수 있는 OpenIfExists 같은 CollisionOption 을 사용할 수가 없네요. BroadFileSystemAccess 을 사용해도 마찬가지 인것 같고요

picker 를 이용하지 않고 UWP 사용자 폴더의 파일이나 폴더에 접근하여 가져오고 데이터를 쓰고 하는 다른 방법이 있을까요?


6-1. Create


        private async void CreateFileInSelectedFolder()
        {
            if (_selectedFolder == null) return;
            var file = await _selectedFolder.CreateFileAsync("TextFile.tmp", CreationCollisionOption.OpenIfExists);
            if (file == null) return;
            var msg = new MessageDialog("Successful creation or opening operation");
            await msg.ShowAsync();
        }



6-2. Open


        private async void OpenFile()
        {
            if (_selectedFolder == null) return;
            try
            {
                var file = await _selectedFolder.GetFileAsync("TextFile.tmp");
                if (file == null) return;
                var msg = new MessageDialog("Successful opening operation");
                await msg.ShowAsync();
            }
            catch (FileNotFoundException ffe)
            {
                var msg = new MessageDialog(ffe.Message);
                await msg.ShowAsync();
            }
            catch (Exception)
            {
                throw;
            }
        }


문의하신 내용에 대한 답변이 되었는지 모르겠습니다. 추가로 궁금하신 사항은 다시 적어주세요 감사합니다.


소스도 올려 놓았으니 참고하세용


2020/06/17 추가

File access permissions


현재 윈도우 버전에서는 File System에 접근을 허용해야지만 엑세스가 가능합니다. 위의 내용을 참고하세요

그리고, 소스는 오늘날짜로 업데이트 했습니다.


2021/01/14 추가

UnauthorizedAccessException: Access to the path "E:\ XXX.dbf" is denied. 이런식으로 뜨는데 어떻게해야 접근 가능할까요?

오류 내용 확인이 필요합니다.


반응형
댓글