MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
444 stars 53 forks source link

WinRT DataReader.ReadBytes throws "Invalid number of parameters" error on WebView2 #3454

Closed emre-ozgu closed 4 weeks ago

emre-ozgu commented 1 year ago

Description The documentation for DataReader.ReadBytes (https://learn.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader.readbytes?view=winrt-22621) shows that we need to pass an array that will store the bytes that are read. This is how we were using it on WebView1 from JavaScript as well.

On WebView2, calling this method in the same way from JavaScript throws an Invalid number of parameters. 0x8002000E error.

Version WebView2 Version: 1.0.1777-prerelease Framework: UWP, WinRT OS: Win10

Repro Steps:

  1. Create a WinRT on UWP project with WebView2 following https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/winrt-from-js?tabs=winui2%2Cwinrtcsharp
  2. Run the app. Open the DevTools console and try the following:
    const Windows = chrome.webview.hostObjects.sync.Windows;
    const capacity = 10;
    const buffer = new Windows.Storage.Streams.Buffer(capacity);
    const dataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer);
    const bytes = new Uint8Array(capacity);
    dataReader.readBytes(bytes);

Output:

Uncaught Error: Invalid number of parameters. (0x8002000E)
    at RemoteMessenger.postSyncRequestMessage (<anonymous>:1:16533)
    at Function.applyHostFunction (<anonymous>:1:32907)
    at Object.apply (<anonymous>:1:22804)
    at <anonymous>:1:12

Additional Context

  1. If I'm understanding the Windows.Storage.Streams.g.cpp file generated from wv2winrt correctly, this seems to expect no parameters despite the documentation:

    
    // Invoke for method ReadBytes
    if (0 == dispParams->cArgs)
    {
    hr = S_OK;
    try
    {
        auto innerObject = m_innerObject.as<winrt::Windows::Storage::Streams::IDataReader>();
        // IDispatch::Invoke DISPPARAMS are in reverse order so we do Count - ParamIdx - 1 below
    innerObject.ReadBytes(
            RefConverter<winrt::array_view<uint8_t>, VARIANT>(m_dispatchAdapter).ConvertOut(
                result
            ) // Out
    );
    
    }
    catch (winrt::hresult_error)
    {
        hr = winrt::to_hresult();
    }
    catch (...)
    {
        hr = E_UNEXPECTED;
    }
    }

else { hr = DISP_E_BADPARAMCOUNT; }


2. Calling `DataReader.readBytes()` with no paramaters goes through and it returns an array, but the returned array is empty.

Input:

Windows.Storage.FileIO.ReadBufferAsync(file) .then((buffer) => { const dataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer); console.log(dataReader.readBytes()); });

Output:

[]



[AB#45973937](https://microsoft.visualstudio.com/90b2a23c-cab8-4e7c-90e7-a977f32c1f5d/_workitems/edit/45973937)
david-risney commented 1 year ago

Thanks for reporting this issue! ReadBytes has one out parameter and since JavaScript doesn't support out parameters wv2winrt turns that into a return value (see more info on how wv2winrt handles out parameters) - which you figured out from looking at the generated code. So it should be dataReader.readBytes() like you have, but it should be giving you a JavaScript array of the bytes of the file and not an empty array. I've filed a bug to track this, thanks!

vagisha-nidhi195 commented 1 year ago

Any update on this @david-risney ? It is blocking us from implementing some critical functionality in a webview2 app.

david-risney commented 1 year ago

Unfortunately no update yet. You may be able to workaround the issue by creating your own WinRT runtimeclass with method to operate on the data reader or return the values you need with a different type.

josephsobhy commented 3 months ago

This is now fixed in edge 126 and webview2 sdk 1.0.2535.41.

you'll need to set the host objects option for chrome.webview.hostObjects.options.shouldPassTypedArraysAsArrays to true.

Also readBytes is not returning the result not the passed out param.

Please feel free to resolve.

champnic commented 4 weeks ago

Thanks for confirming @josephsobhy!