Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#603 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
35/100
issue の種類
ドキュメント
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
cpp, react-native

調査の方向性

リンク先の「Using UIDispatcher with C++/WinRT」ドキュメントから始め、その例を ClipboardModule.cpp、AccessibilityInfoModule.cpp、ImageViewManagerModule.cpp、AlertModule.cpp と比較してください。UIDispatcher callback が promise を返す、または reject する方法を、FileOpenPicker や LaunchFileAsync の結果も含めて明確にし、ドキュメントに記載された使用方法でクラッシュが発生しないことを確認してください。

索引モデルが issue の本文から書いたものです。

説明

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() });
    }
}
主要言語
C#
スター
544
フォーク
218
PR マージ指標
30日以内にマージされた PR はありません

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/react-native-windows-samples のほかの issue

microsoft/react-native-windows-samples の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。