-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UIDispatcher how to return value/resolve/reject promise without crash? (Documentation unlcear) #603
Comments
Thanks for the detailed issue report, @creambyemute. Sorry that the documentation hasn't been clear here. Let me see if we can bring in someone to help unblock you and also get the documentation better expanded for the next person. Since I think this is a documentation issue I'll move to the repo where that article lives. |
I have got it working now. Turns out, the comment When using The Is there any way to use Edit: According to #427 (comment) it may be possible with a winrt::fire_and_forget FileOpener::openFileAsync(std::string filepath, bool showOpenWithDialog, RN::ReactPromise<void> promise) noexcept
try {
std::filesystem::path fPath{ filepath };
fPath.make_preferred();
auto jsDispatcher = m_reactContext.JSDispatcher();
try {
StorageFile file{ co_await StorageFile::GetFileFromPathAsync(winrt::to_hstring(fPath.c_str())) };
try {
if (file) {
m_reactContext.UIDispatcher().Post([showOpenWithDialog, file, promise, fPath, jsDispatcher] {
LauncherOptions launchOptions;
launchOptions.DisplayApplicationPicker(showOpenWithDialog);
IAsyncOperation<bool> asyncLaunchFileOp = Launcher::LaunchFileAsync(file, launchOptions);
asyncLaunchFileOp.Completed([jsDispatcher, promise, fPath](const IAsyncOperation<bool>& asyncLaunchFileOp, AsyncStatus status) {
switch (status) {
case AsyncStatus::Completed: {
bool success = asyncLaunchFileOp.GetResults();
if (success) {
jsDispatcher.Post([promise] { promise.Resolve(); });
}
else {
jsDispatcher.Post([promise, fPath] { promise.Reject(RN::ReactError{ "Unable to open File", winrt::to_string(fPath.c_str()) }); });
}
break;
}
case AsyncStatus::Canceled: {
jsDispatcher.Post([promise, fPath] { promise.Reject(RN::ReactError{ "Unable to open File", winrt::to_string(fPath.c_str()) }); });
break;
}
case AsyncStatus::Error: {
auto message = std::wstring(winrt::hresult_error(asyncLaunchFileOp.ErrorCode()).message());
jsDispatcher.Post([promise, message, fPath] { promise.Reject(RN::ReactError{ "Unable to open File" + winrt::to_string(fPath.c_str()), winrt::to_string(message.c_str()) }); });
break;
}
case AsyncStatus::Started: {
jsDispatcher.Post([promise, fPath] { promise.Reject(RN::ReactError{ "Unable to open File", winrt::to_string(fPath.c_str()) }); });
break;
}
}
});
});
} else {
promise.Reject(RN::ReactError{ "Unable to open File", winrt::to_string(fPath.c_str()) });
}
} catch (const hresult_error& ex) {
promise.Reject(RN::ReactError{ "Unable to LaunchFileAsync for File " + filepath, winrt::to_string(ex.message()).c_str() });
}
} catch(const hresult_error& ex) {
promise.Reject(RN::ReactError{ "Unable to GetFileFromPathAsync for File " + filepath, winrt::to_string(ex.message()).c_str() });
}
} catch(const hresult_error& ex) {
promise.Reject(RN::ReactError{ "Unable to make path or make_preferred for File " + filepath, winrt::to_string(ex.message()).c_str() });
} |
Problem Description
I have two small native c++ modules which use the
Launcher::LaunchFileAsync
andFileOpenPicker::pickSingleFileAsync
.After upgrading from 0.63 to 0.65 we have to use the UIDispatcher in order for it to work. So I had a look at the following Documentation:
Using UIDispatcher with C++/WinRT
Unfortunately, the example lacks the bit about how to return a value from there (in that example, that would probably be the
file.Path()
).So I digged a bit further and had a look at the following 4 modules inside react-native-windows:
Clipboard Module
AccessibilityInfoModule
ImageViewManagerModule
AlertModule
I tried multiple different variations now and had a look at the crash dump but I always crash with an
Access Violation
on thepromise.resolve
line.What am I doing wrong there? I don't see a lot of differences between my code and the above modules despite the
co_await
usage.I'm also having the same problem with FileOpenPicker where I'd want to resolve the
tempFile.Path()
after picking+moving it to the apps temp folder (StorageFile tempFile{ co_await file.CopyAsync(winrt::Windows::Storage::ApplicationData::Current().TemporaryFolder(), file.Name(), NameCollisionOption::ReplaceExisting) };
)Steps To Reproduce
NativeModules.FileOpener.openFileAsync(filePath, shouldShowOpenWithDialog)
Expected Results
Not crash, resolve the promise to JS.
Documentation to reflect an actual usage of FileOpenPicker/UIDispatcher with result returns/promise.resolve.
CLI version
6.1.0
Environment
Target Platform Version
10.0.19041
Target Device(s)
Desktop
Visual Studio Version
Visual Studio 2019
Build Configuration
Release
Snack, code example, screenshot, or link to a repository
FileOpener.h
FileOpener.cpp
The text was updated successfully, but these errors were encountered: