6

I have a Win32 programm, where I want to add some winRT calls. Among other things I want to open a file without a GUI interface.

I use the async file open call from the StorageFile class, because the next call needs an IStorageFile interface.

#include <roapi.h>
#include <winrt/Windows.Storage.h> 
#include <winrt/Windows.Foundation.h>

void openFile()
{
   using namespace winrt;
   using namespace winrt::Windows::Foundation;
   using namespace winrt::Windows::Storage;

   HRESULT rtn = RoInitialize(RO_INIT_MULTITHREADED); 
   winrt::hstring path{ L"C:\\Users...\\mytextfile.txt"};

   //wait for open the file 
   auto file = co_await StorageFile::GetFileFromPathAsync(path);

   //IStorageFile interface needed  
}

int main()
{
  openFile(); 
  return 0;
}

At the moment, the compiler complains that the co_await expression requires a suitable "await_ready" function and none was found.

I`m not sure if this is the case due to a missing header include or if "co_await" can not be used within a win32 application.

Edit: My visual studio project setup is: - use c++17, add cppwinrt.exe to my include directories, link against windowsapp.lib and use windows sdk version 10.0.17134.0.

user5580578
  • 1,134
  • 1
  • 12
  • 28

1 Answers1

6

The problem is that the openFile() function does not have the proper return type to handle co_await.

See the research and work that went into the answer I created for C++11 threads to update MFC application windows. SendMessage(), PostMessage() required? which contains a list of recommendations for various approaches to coroutines.

This question was about using C++/WinRT with MFC but the material also applies with WinAPI.

See as well synchronizing SDK with Windows 10 update and using WinRT with Standard C++ which contains a simple console application example using the Web Syndication async functionality to retrieve a list of URLs from an RSS feed. There are a number of links to documentation, some of which is a bit out dated now.

Addendum: Sample Console application

I created the following simple console application using Visual Studio 2017. I created the text file and then ran this in the debugger. I then renamed the text file and ran it again in the debugger and an exception was thrown since the file with that name no longer existed.

See also C++/WinRT, part of Windows SDK 17134 is not compatible with Visual Studio 15.8 Preview 3 which describes a compiler option you may need to change. I did.

// console_winrt.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
// Requires the following changes to the project properties in the C++ compiler section.
//   - C++ language standard must be set to C++17
//   - Add /await to the Additional options

#include "pch.h"

#pragma comment(lib, "windowsapp")

#include <winrt/Windows.Storage.h> 
#include <winrt/Windows.Foundation.h>

#include <iostream>

winrt::Windows::Foundation::IAsyncAction  openMyFile()
{

    winrt::hstring path{ L"D:\\Users\\rickc\\mytextfile.txt" };

    //wait for open the file 
    auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path);

    //IStorageFile interface needed 
    auto xDate = file.DateCreated();
    std::cout << "file was found " << std::endl;
}

int main()
{
    // initialize the WinRT apartment.
    winrt::init_apartment();

    auto x = openMyFile();

    // wait on the file access since that is all we are doing and we need to give it time.
    x.get();
    return 0;
}

I used the following properties settings.

Properties dialog screen shot showing General Properties

Properties dialog screen shot showing C/C++ All options

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
  • Very cool. One further question: how is it possible to wait in the main thread as long as the concurrency tasks is running? – user5580578 Oct 16 '18 at 18:06
  • @user5580578 My understanding is that under the hood there are gnarly bits that do the actual thread management along with the join that is the main thread waiting for the coroutine to complete. The nice thing about coroutines is that they hide the mechanics nicely and are easy to use. – Richard Chambers Oct 16 '18 at 18:10
  • @user5580578 I have updated my answer with a short sample Windows console application using WinRT with `co_await`. I think I have provided all the pertinent details. – Richard Chambers Oct 17 '18 at 00:07
  • Thank you very much for your help! Everything is working as expected. – user5580578 Oct 17 '18 at 16:32
  • 1
    More useful information can be found here: (https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/concurrency) – user5580578 Oct 17 '18 at 16:33