Home > Software design >  Exception in Concurrency task.then.wait affects further call of ::ShellExecuteEx()
Exception in Concurrency task.then.wait affects further call of ::ShellExecuteEx()

Time:12-03

Following logic is implemented to open a file by a "filename.extension" in a C application using managed-C :

try
{
    CoInitialize(nullptr);
    auto task = Concurrency::create_task(Windows::Storage::StorageFile::GetFileFromPathAsync(filePath));
    // an excpetion is thrown in the next line
    Concurrency::task_status status = task.then([&](Windows::Storage::StorageFile^ file){
        if (file != nullptr)
        {
            concurrency::task<bool> launchFileOperation(Windows::System::Launcher::LaunchFileAsync(file));
            launchFileOperation.then([&](bool success)
            {
                if (!success)
                    return 0;
            }).wait();
        }
    }).wait();
}
catch (...)
{
    CoUninitialize(); // an exeption is catched
    return 0;
}

Since the above code throws an exception, we go further to an alternative file open approach via ::ShellExecuteEx

SHELLEXECUTEINFO exec_info = {0};
exec_info.cbSize = sizeof exec_info;
exec_info.fMask  = SEE_MASK_NOCLOSEPROCESS
                | SEE_MASK_DOENVSUBST;   

exec_info.fMask &= ~SEE_MASK_NOASYNC;
exec_info.lpVerb = "open";
exec_info.lpFile = full_path_str;
exec_info.nShow  = SW_SHOW;

bool result_b = ::ShellExecuteEx(&exec_info) ? true : false;

The ::ShellExecuteEx fails and ends up in Microsofts ppltasks.h _REPORT_PPLTASK_UNOBSERVED_EXCEPTION();.

::ShellExecuteEx works correctly if the managed-C Concurrency::create_task approach is removed.

Why does Concurrency::create_task affect the further call of ::ShellExecuteEx?

This issue appears only in release build.

CodePudding user response:

Adding try/catch-blocks to the innermost .wait()-block solved the issue

try {

   concurrency::task<bool> launchFileOperation(Windows::System::Launcher::LaunchFileAsync(file));
   launchFileOperation.then([&](bool success) {
      // logic
      }).wait();
}
catch (concurrency::invalid_operation& ex) 
{
    ... 
}
catch (concurrency::task_canceled& ex) 
{
    ...
}
  • Related