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)
{
...
}