Как пересчитать содержимое папок в октябре 2018 г.

Пытаясь перевести на cppwinrt метод StorageFolder GetFilesAsync, я не могу исправить ошибки ссылки компилятора. Вот очень простая процедура проверки концепции:

#include "winrt/Windows.Storage.h" 
#include "winrt/Windows.Foundation.Collections.h"
IAsyncAction TestClass::LoadFiles()
{
    StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation(); 
    StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(hstring(L"Assets")); 
    auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery); 
}

Проблема, похоже, кроется в возвращаемом типе GetFilesAsync. Я пробовал для этого разные типы, например IVectorView, но вроде ничего не работает. Кто-нибудь знает пример кода, показывающий, как это перечисление может быть выполнено в C ++ / winrt?

[ОБНОВЛЕНИЕ] Возвращаясь к этому проекту с SDK 10.0.17666 и VS 15.9.0 Preview 3, я обнаружил, что решение, принятое ранее из этих ответов, больше не работает. На этот раз я обязательно включу полную ошибку, чтобы посмотреть, есть ли у кого-нибудь идеи. Для простоты я буду использовать только простой код, предоставленный IInspectable, измененный только для того, чтобы сделать его членом класса в моем классе ResourceManager:

 #include "winrt/Windows.ApplicationModel.h"
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Storage.Search.h"
#include "winrt/Windows.UI.Core.h"
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;

IAsyncAction ResourceManager::LoadActivities()
{
    StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
    StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Activities");
    auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}

Вызов GetFilesAsync теперь вызывает следующую ошибку ссылки: Код серьезности Описание Ошибка состояния подавления строки файла проекта LNK2019 неразрешенный внешний символ "public: struct winrt :: Windows :: Foundation :: IAsyncOperation> __thiscall winrt :: impl :: consumer_Windows_Storage_Search_IStorageFolderQueryOperations :: GetFiles (перечисление winrt :: Windows :: Storage :: Search :: CommonFileQuery const &) const "(? GetFilesAsync @? $ consumer_Windows_Storage_Search_IStorageFolderQueryOperations @ UStorageFolder @ Storage @ Windows @ winrt @@@ impl @ winrt @@ QBE? AU? @ $ IAsyncOperation U? $ IVectorView @ UStorageFile @ Storage @ Windows @ winrt @@@ Collections @ Foundation @ Windows @ winrt @@@ Foundation @ Windows @ 3 @ ABW4CommonFileQuery @ Search @ Storage @ 63 @@ Z), указанного в функции "public: struct winrt :: Windows :: Foundation :: IAsyncAction __thiscall AppEngine :: ResourceManager :: LoadActivities $ _ResumeCoro $ 2 (void) "(? LoadActivities $ _ResumeCoro $ 2 @ ResourceManager @ AppEngine @@ QAE? AUIAsyncAction @ Foundation XZ @ winrt

(далее следует путь к объектному файлу)

Должен признаться, мне трудно расшифровать это сообщение об ошибке. Может быть, у кого-нибудь из присутствующих появится идея? Должно быть что-то, что изменилось в последних обновлениях системы.


person user3743210    schedule 11.02.2018    source источник
comment
Поделитесь, пожалуйста, актуальными ошибками. Без этой информации вы оставляете всех размышлять о том, чего не хватает. Я подозреваю, что вам не хватает #include, но это всего лишь обоснованное предположение.   -  person Ryan Shepherd    schedule 12.02.2018
comment
Кроме того, явное построение hstring вокруг LAsset не требуется и фактически снижает производительность.   -  person Ryan Shepherd    schedule 12.02.2018
comment
Спасибо - ошибка слишком длинная, чтобы уместиться в комментарии, поэтому здесь она сокращена: LNK2019 неразрешенный внешний символ public: struct winrt :: Windows :: Foundation :: IAsyncOperation ‹struct winrt :: Windows :: Foundation :: Collections :: IVectorView ‹Struct winrt :: Windows :: Storage :: StorageFile› ›__cdecl winrt :: impl :: consumer_Windows_Storage_Search_IStorageFolderQueryOperations‹ struct winrt :: Windows :: Storage :: StorageFolder ›:: GetFilesAsync (enum winrt :: Windows :: Storage :: Search :: CommonFileQuery const &) const (? GetFilesAsync @?   -  person user3743210    schedule 12.02.2018
comment
Не размещайте важную информацию в комментариях. Вместо этого отредактируйте свой вопрос и добавьте туда сообщения об ошибках.   -  person IInspectable    schedule 12.02.2018


Ответы (1)


Как бы то ни было, следующий автономный код компилируется отлично. Таким образом, вам, вероятно, не хватает #include или библиотеки ссылок, но невозможно сказать, если вы не делитесь важной информацией, например какие фактические ошибки вы видите.

#pragma comment(lib, "WindowsApp")

#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Search.h>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;

IAsyncAction LoadFiles()
{
    StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
    StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Assets");
    auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}

int main()
{
    LoadFiles().get();
}
person Ryan Shepherd    schedule 12.02.2018
comment
Спасибо! Это очень полезно, Райан. Похоже, мне не хватало только #include для Storage.Search.h - у меня был Storage.h, но не он. Это компилируется и запускается! И я обнаружил, что тип возвращаемого значения - winrt :: Windows :: Foundation :: Collections :: IVectorView ‹winrt :: Windows :: Storage :: StorageFile›, так что теперь нужно выяснить, как работать с IVectorView. Я действительно надеялся, что это приведет к преобразованию в std :: vector ‹StorageFile›. - person user3743210; 12.02.2018
comment
p.s. Единственное, что у меня не работает и не работает, когда я использовал IAsyncAction для других вызовов, - это метод .get (). Если я вызываю LoadFiles (). Get (); для подобного AsyncAction с именем LoadFiles () я получаю сбой: template ‹typename Async› void blocking_suspend (Async const & async) noexcept {WINRT_ASSERT (! is_sta ()); - person user3743210; 12.02.2018
comment
.get () блокирует текущий поток, ожидая результата. Когда у вас есть приложение с пользовательским интерфейсом, вы не можете заблокировать основной поток / поток пользовательского интерфейса. В целом это хорошая практика и принудительное ограничение в WinRT. В примере XamlCode есть хороший пример того, как использовать co_await в сопрограмме, а затем переключиться обратно в поток пользовательского интерфейса для публикации результатов. - person Ryan Shepherd; 12.02.2018
comment
Вы можете передать std :: vector методу, ожидающему IVectorView как input, но это преобразование не работает в обратном порядке - интерфейс IVectorView более строг, чем std :: vector. Однако C ++ / WinRT значительно упрощает работу с IVectorView. Вы можете заставить итераторы начала / конца взаимодействовать с остальной частью STL и с циклами for на основе диапазона. - person Ryan Shepherd; 12.02.2018
comment
Получается, что я не должен пытаться использовать IAsyncAction и .get () в приложении с пользовательским интерфейсом? Вместо этого XamlCode использует fire_and_forget. Я могу запустить это без сбоев, адаптировавшись из образца XamlCode. Папка, которую я пытаюсь перечислить, так и не была найдена, но я полагаю, что это еще один недостаток в моей работе. Мне нужно будет провести еще несколько исследований, чтобы найти ответы на такие вопросы, как: как узнать, что асинхронное действие завершилось? - person user3743210; 12.02.2018
comment
Вы можете использовать IAsyncAction и проверить его статус, но вы не можете использовать get (), потому что это часть, которая блокирует. Или вы можете просто использовать сопрограмму co_await для действия и продолжить там свою работу, при необходимости переключившись на поток пользовательского интерфейса. - person Ryan Shepherd; 14.02.2018
comment
Большое спасибо, Райан. - person user3743210; 15.02.2018