C++中的WinRT异步文件操作

Jef*_*eff 0 visual-c++ microsoft-metro windows-runtime c++-cx visual-c++-2012

我目前正在开发一个需要一些文本资源的城域应用程序.构建过程的一部分是将所有这些资源复制到应用程序安装目录中的文件夹中.我想做的是收集这些资源文件的列表,并相应地处理每个文件.不幸的是,我这样做的尝试并不成功.

由于我正在为WinRT构建,我无法使用非常有用的"FindFirstFile"和"FindNextFile"函数.我一直在尝试使用WinRT异步文件IO操作完成工作.

auto getResourceFolder = installedLocation->GetFolderFromPathAsync(  folderPath  );

getResourceFolder->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< Windows::Storage::StorageFolder^ >( 
[this]( Windows::Foundation::IAsyncOperation< Windows::Storage::StorageFolder^ >^ operation ) {

    if( operation->Status == Windows::Foundation::AsyncStatus::Completed ) {

        auto resourceFolder = operation->GetResults();
        auto getResourceFiles = resourceFolder->GetFilesAsync();
        getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView< Windows::Storage::IStorageFile^ >^ >( 
        [this]( Windows::Foundation::IAsyncOperation< IVectorView< Windows::Storage::IStorageFile^ >^ >^ operation ) {

            if( operation->Status == Windows::Foundation::AsyncStatus::Completed ) {

                auto resourceFiles = operation->GetResults();

                for( unsigned int i = 0; i < resourceFiles->Size; ++i ) {

                    // Process File
                }

            }

        });

    }

});
Run Code Online (Sandbox Code Playgroud)

哪个编译失败:

错误C2664:'Windows :: Foundation :: IAsyncOperation <TResult> :: Completed :: set':无法将参数1从'Windows :: Foundation :: AsyncOperationCompletedHandler <TResult> ^'转换为'Windows :: Foundation :: AsyncOperationCompletedHandler < TResult> ^'

这个错误对我没有任何意义.我已经尝试重写上面的代码,以便lambda处理函数不是内联的,但它没有什么区别.我不确定是什么问题.

有任何想法吗?提前致谢.

Jam*_*lis 5

[注意:为简洁起见,我从代码和错误消息中省略了大多数命名空间限定.]

Visual Studio错误列表窗格仅显示每个错误的第一行(这是一个非常有用的功能,尤其是在使用C++编程时,因为编译器的一些错误消息非常长.您需要查看"输出"窗口以查看其余的错误信息:

error C2664: 'IAsyncOperation<TResult>::Completed::set' : 
cannot convert parameter 1 
    from 'AsyncOperationCompletedHandler<TResult> ^'
    to   'AsyncOperationCompletedHandler<TResult> ^'
with
[
    TResult=IVectorView<StorageFile ^> ^ 
]
and
[
    TResult=IVectorView<IStorageFile ^> ^
]
and
[
    TResult=IVectorView<StorageFile ^> ^
]
No user-defined-conversion operator available, or
Types pointed to are unrelated;
conversion requires reinterpret_cast, C-style cast or function-style cast
Run Code Online (Sandbox Code Playgroud)

这仍然有点令人困惑,因为所有三个模板都使用名为的参数TResult.要解密错误,请注意第一行中模板的顺序与行的其余部分中的模板参数列表的顺序相匹配.

这里的问题是你混合使用StorageFileIStorageFile.在这两行中,您需要使用StorageFile(请参阅使用位置的行下的胡萝卜IStorageFile):

getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView< Windows::Storage::IStorageFile^ >^ >( 
                                                                                                                          ^
[this]( Windows::Foundation::IAsyncOperation< IVectorView< Windows::Storage::IStorageFile^ >^ >^ operation ) {
                                                                             ^
Run Code Online (Sandbox Code Playgroud)

请注意,一旦解决了这个问题,你就会得到另一对错误,因为你的lambdas需要有两个参数; 第二个是AsyncStatus.最后,它们都应该被声明为:

// Namespaces omitted for brevity
[this](IAsyncOperation<StorageFolder^>^ operation, AsyncStatus status) { }
Run Code Online (Sandbox Code Playgroud)

由于我建设WinRT的,我不能使用非常有用FindFirstFileFindNextFile功能.

需要注意的是,你可以,事实上,同时使用FindFirstFileExFindNextFile在Metro风格应用.(非Ex FindFirstFile不可用).

您应该尽可能在任何可能的地方使用异步WinRT函数,但这并不意味着这些其他函数仍然没有用处.