• UWP이 로컬 파일 시스템을 직접 접근해서 파일이나 폴더의 정보를 가지고 오는 방법에 대한 설명입니다.

  • This is how UWP directly accesses the local file system and fetches information from files or folders.

  • BroadFileSystemAccess

    • All Files that the user has access to
    • Settings } Privacy | File system | Allow access UWP app
    • Version 1803 - default is On
    • Version 1809 - default is Off
    • This capability is not supported on Xbox
  • Key Point

    • Package.appxmanifest } Mouse Right Click } Open With… } XML (Text) Editor
    • Add rescap namespace
    • Add rescap:Capability to th Capabilities section
      • {rescap:Capability Name="broadFileSystemAccess" /}
    • Code
      • var folder = await StorageFolder.GetFolderFromPathAsync(path);
      • try-catch(UnauthorizedAccessException)
  • Completed sample app

  - youtu.be/TJ5wDDgty6A

 

'Windows App(Universal App) > Beginner' 카테고리의 다른 글

Microsoft Edge(Chromium) WebView2 Control  (0) 2020.08.17
Face detecting in UWP app  (0) 2020.08.06
Create a UWP app with File System Access  (0) 2020.07.24
Install and update UWP apps from the Web  (0) 2020.04.25
LINQ - Join Operations - part5/5  (0) 2020.04.15
LINQ part 4  (0) 2020.02.11
블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요


오랜만에 포스트를 작성하네요. 음..변명을 하자면.. 챗봇 공부를 하고 있는 중이였는데 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 추가


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


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

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


블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

  • 2018.06.01 14:37  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  • kaki104 2018.06.04 23:00 신고  댓글주소  수정/삭제  댓글쓰기

    http://kaki104.tistory.com/582
    문의하신 내용에 대해서 간단하게 답변을 추가했습니다. 확인하시고 궁금하신 사항은 다시 문의 주세요

  • kiokju 2020.03.09 17:14  댓글주소  수정/삭제  댓글쓰기

    유니티로 작업중인데 Videos 폴더에 비디오 파일을 넣고 비디오 플레이어에 경로를 주려고합니다.
    Access denied 에러가 발생합니다.
    위의 퍼미션을 주어도 계속 발생하는데 방법이 없는지요.

    • kaki104 2020.03.11 20:50 신고  댓글주소  수정/삭제

      Package.appxmanifest -> Capabilities -> Video Library를 체크 하시면 Videos 폴더에 있는 파일을 엑세스 하실 수 있습니다.

      private async void Button_Click(object sender, RoutedEventArgs e)
      {
      var picker = new FileOpenPicker();
      picker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
      picker.FileTypeFilter.Add(".mp4");

      var file = await picker.PickSingleFileAsync();
      if (file.IsAvailable == false) return;
      MediaElement.SetSource(await file.OpenReadAsync(), file.ContentType);
      }
      대략 이렇거하시면 될 것 같습니다.
      저 권한을 안주셔서 접근 거부가 나온듯 합니다.

  • qwe 2020.06.08 11:17  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, 코드 감사합니다. 한가지 여쭤보려고 댓글 답니다. ㅠㅠ

    'System.UnauthorizedAccessException' 형식의 예외가 System.Private.CoreLib.dll에서 발생했지만 사용자 코드에서 처리되지 않았습니다.
    액세스가 거부되었습니다. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

    var rootFolder = await StorageFolder.GetFolderFromPathAsync(@"c:\"); 이 부분에서 에러가 나는데 왜 나는지 걸까요?

    manifast도 추가해줬고, 나머지 코드들은 다 붙여넣는데 그 부분에서 에러가 나네요. 바쁘시지 않으시다면 답변 부탁드립니다. ㅠㅠ

    • kaki104 2020.06.17 21:23 신고  댓글주소  수정/삭제

      https://docs.microsoft.com/en-us/windows/uwp/files/file-access-permissions
      이곳에 에러가 발생하는 이유가 있네요, 1809가 처음나왔을 때는 이런 내용이 없었는데, 지금은 파일 시스템 접근을 허용해야지만 접근이 가능합니다. 소스를 업데이트 했으니 Sync를 해서 새로 받으신 후에 실행하시면 잘 되실 것 같습니다.