WebView2Feedback icon indicating copy to clipboard operation
WebView2Feedback copied to clipboard

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

Open emre-ozgu opened this issue 2 years ago • 4 comments

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;
}
  1. 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

emre-ozgu avatar May 03 '23 20:05 emre-ozgu

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!

david-risney avatar May 05 '23 18:05 david-risney

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

vagisha-nidhi195 avatar May 23 '23 09:05 vagisha-nidhi195

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.

david-risney avatar May 23 '23 16:05 david-risney

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.

josephsobhy avatar Jul 02 '24 12:07 josephsobhy

Thanks for confirming @josephsobhy!

champnic avatar Sep 05 '24 23:09 champnic