Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

UIDispatcher how to return value/resolve/reject promise without crash? (Documentation unlcear)

Đang mở
#603 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
35/100
Loại issue
Tài liệu
Độ rõ ràng
Cần làm rõ
Mức độ hoạt động
Đình trệ
Công nghệ
cpp, react-native
Lĩnh vực
desktop, documentation

Hướng nghiên cứu

Bắt đầu với tài liệu được liên kết “Using UIDispatcher with C++/WinRT” và so sánh ví dụ trong đó với ClipboardModule.cpp, AccessibilityInfoModule.cpp, ImageViewManagerModule.cpp và AlertModule.cpp. Làm rõ cách một callback của UIDispatcher trả về hoặc từ chối một promise, bao gồm cả kết quả từ FileOpenPicker hoặc LaunchFileAsync, và đảm bảo cách sử dụng được ghi trong tài liệu không gây crash.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

documentation enhancement
Problem Description

I have two small native c++ modules which use the Launcher::LaunchFileAsync and FileOpenPicker::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 the promise.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
  1. Init a new project
  2. Add the FileOpener posted below to the project
  3. Add an openable file to the application folder (for example a pdf)
  4. Call 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
info Fetching system and libraries information...
System:
    OS: Windows 10 10.0.19043
    CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
    Memory: 24.72 GB / 31.94 GB
  Binaries:
    Node: 14.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.11 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.11 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 28, 29, 30
      Build Tools: 29.0.0, 29.0.1, 29.0.2, 29.0.3, 30.0.0, 30.0.1, 30.0.2, 30.0.3
      System Images: android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
    Windows SDK:
      AllowDevelopmentWithoutDevLicense: Enabled
      AllowAllTrustedApps: Enabled
      Versions: 10.0.16299.0, 10.0.17134.0, 10.0.17763.0, 10.0.18362.0, 10.0.19041.0
  IDEs:
    Android Studio: Not Found
    Visual Studio: 16.9.31313.79 (Visual Studio Community 2019)
  Languages:
    Java: 1.8.0_282 - /c/Program Files/OpenJDK/openjdk-8u282-b08/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.65.2 => 0.65.2
    react-native-windows: ^0.65.7 => 0.65.7
  npmGlobalPackages:
    *react-native*: Not Found
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

#pragma once

#include "pch.h"
#include "NativeModules.h"
#include <string>

namespace RN = winrt::Microsoft::ReactNative;

namespace inspection::FileOpener {
    REACT_MODULE(FileOpener, L"FileOpener");
    struct FileOpener final {
        RN::ReactContext m_reactContext;

        REACT_INIT(Initialize)
            void Initialize(RN::ReactContext const& reactContext) noexcept;

        REACT_METHOD(openFileAsync)
        winrt::fire_and_forget openFileAsync(std::string filepath, bool showOpenWithDialog, RN::ReactPromise<void> promise) noexcept;
    };
}

FileOpener.cpp

#include "pch.h"

#include "FileOpener.h"

#include <filesystem>
#include <windows.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.System.h>

using namespace winrt;
using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Foundation;
using namespace Windows::System;

namespace inspection::FileOpener {
    void FileOpener::Initialize(RN::ReactContext const& reactContext) noexcept {
        m_reactContext = reactContext;
    }

    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]()->winrt::fire_and_forget {
                        LauncherOptions launchOptions;
                        launchOptions.DisplayApplicationPicker(showOpenWithDialog);
                        bool success{ co_await Launcher::LaunchFileAsync(file, launchOptions) };
                        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()) }); });
                        }
                    });
                } 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() });
    }
}
Ngôn ngữ chính
C#
Star
544
Fork
218
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

  • Có Dockerfile hoặc tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của microsoft/react-native-windows-samples

Tất cả issue của microsoft/react-native-windows-samples

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.