Skip to content

Add demo scenario for Bug #5227 in WebMessageObjects API #275

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.1" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.3.230602002">
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.3916" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@

mc:Ignorable="d">


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>

<Grid Grid.Row="0" Background="LightGray">
<MenuBar Grid.Row="0">
<MenuBarItem Title="Scenarios">
<MenuFlyoutItem Text="Share File Handles" Click="MenuFlyoutItem_Click"/>
</MenuBarItem>
</MenuBar>
<Grid Grid.Row="1" Background="LightGray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
Expand All @@ -25,9 +31,9 @@
<Button Grid.Column="1" x:Name="Go" Content="Go" Click="Go_OnClick" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>

<WebView2 x:Name="WebView2" Grid.Row="1"/>
<WebView2 x:Name="WebView2" Grid.Row="2"/>

<Rectangle Grid.Row="2" Fill="LightGray"/>
<TextBlock x:Name="StatusBar" Text="WebView2" VerticalAlignment="Center" Grid.Row="2" Margin="10,0,10,0"/>
<Rectangle Grid.Row="3" Fill="LightGray"/>
<TextBlock x:Name="StatusBar" Text="WebView2" VerticalAlignment="Center" Grid.Row="3" Margin="10,0,10,0"/>
</Grid>
</Window>
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,10 @@ private string GetWebView2Version(WebView2 webView2)

return $"{runtimeVersion}; {sdkVersion}";
}

private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
new Scenario_FileHandle().Execute(WebView2);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.Web.WebView2.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.UI.Popups;

namespace WebView2_WinUI3_Sample
{
internal class Scenario_FileHandle
{
private WebView2 _webView;

public void Execute(WebView2 webView)
{
_webView = webView;
webView.CoreWebView2.Settings.IsWebMessageEnabled = true;
webView.CoreWebView2.PermissionRequested += CoreWebView2_PermissionRequested;
webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
webView.CoreWebView2.SetVirtualHostNameToFolderMapping("content.app",
Path.Combine(Package.Current.InstalledLocation.Path, "assets"),
CoreWebView2HostResourceAccessKind.Allow);
webView.Source = new Uri("https://content.app/ScenarioFileHandle.html");
}

private void SendDirAndFileHandleFromNativeToJS()
{
var dirHandle = _webView.CoreWebView2.Environment.CreateWebFileSystemDirectoryHandle(
Path.Combine(Package.Current.InstalledLocation.Path, "assets"),
CoreWebView2FileSystemHandlePermission.ReadWrite);
var fileHandle = _webView.CoreWebView2.Environment.CreateWebFileSystemFileHandle(
Path.Combine(Package.Current.InstalledLocation.Path, "assets", "ScenarioFileHandle.html"),
CoreWebView2FileSystemHandlePermission.ReadOnly);
_webView.CoreWebView2.PostWebMessageAsJson("{}", new List<object> { dirHandle, fileHandle });
}

private void CoreWebView2_PermissionRequested(CoreWebView2 sender, CoreWebView2PermissionRequestedEventArgs args)
{
//allow all permission requests for demo purpose
args.State = CoreWebView2PermissionState.Allow;
}

private async void CoreWebView2_WebMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
{
if (args.WebMessageAsJson == "\"requestWorkingDir\"")
{
SendDirAndFileHandleFromNativeToJS();
}

foreach (var item in args.AdditionalObjects)
{
if (item == null)
{
var messageDialog = new ContentDialog()
{
Title = "Error",
Content = "Received additional object is <null>, Expected: CoreWebView2FileSystemHandle",
CloseButtonText = "Ok"
};
messageDialog.XamlRoot = _webView.XamlRoot;
await messageDialog.ShowAsync();
}
Debug.Assert(item is CoreWebView2FileSystemHandle);
Debug.Assert(item != null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
<UseWinUI>true</UseWinUI>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<None Remove="assets\ScenarioFileHandle.html" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.3.230602002" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3240.44" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.3916" />
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Native to web</h1>
<div>PWA requires write access to a working directory in the file system. <br /> e.g. to launch installed desktop applications from the native part (like Word for DOCX files)</div>
<button onclick="requestDirFromNative()">Request Directory Access</button>
<div id="native2webResult"></div>
<h1>Web to native</h1>
<div>PWA requires write access to user selected directory in the file system. <br /> e.g. to launch installed desktop applications from the native part (like Word for DOCX files)</div>
<h2>Directory handle</h2>
<div>Sending the handle of the selected directory</div>
<button onclick="sendDirHandle()">Open Directory</button>
<h2>File handle</h2>
<div>Sending the handle of a just created file</div>
<button onclick="sendNewFileHandle()">Open Directory</button>
<h2>File handle</h2>
<div>Sending the handle of an existing file</div>
<button onclick="sendExistingFileHandle()">Open Directory</button>
<h2>File handle</h2>
<div>Sending the File object to the handle of an existing file</div>
<button onclick="sendExistingFile()">Open Directory</button>

<script>
async function requestDirFromNative() {
window.chrome.webview.postMessage("requestWorkingDir");
}

async function sendDirHandle() {
const dirHandle = await window.showDirectoryPicker();
let additionalObjects = [dirHandle];
try {
window.chrome.webview.postMessageWithAdditionalObjects("sendDirHandle", additionalObjects);
} catch (e) {
alert("Error: " + e);
}
}
async function sendNewFileHandle() {
const dirHandle = await window.showDirectoryPicker();
const fileHandle = await dirHandle.getFileHandle("temp.bin", { create: true });
const writable = await fileHandle.createWritable();
await writable.close();
const additionalObjects = [fileHandle];
try {
window.chrome.webview.postMessageWithAdditionalObjects("sendNewFileHandle", additionalObjects);
} catch (e) {
alert("Error: " + e);
}
}
async function sendExistingFileHandle() {
const dirHandle = await window.showDirectoryPicker();
const fileHandle = await dirHandle.getFileHandle("temp.bin", { create: true });
const writable = await fileHandle.createWritable();
await writable.close();
const fileHandle2 = await dirHandle.getFileHandle("temp.bin");
const file2 = await fileHandle2.getFile();
const additionalObjects = [fileHandle2];
try {
window.chrome.webview.postMessageWithAdditionalObjects("sendExistingFileHandle", additionalObjects);
} catch (e) {
alert("Error: " + e);
}
}
async function sendExistingFile() {
const dirHandle = await window.showDirectoryPicker();
const fileHandle = await dirHandle.getFileHandle("temp.bin", { create: true });
const writable = await fileHandle.createWritable();
await writable.close();
const fileHandle2 = await dirHandle.getFileHandle("temp.bin");
const file2 = await fileHandle2.getFile();
const additionalObjects = [file2];
try {
window.chrome.webview.postMessageWithAdditionalObjects("sendExistingFileHandle", additionalObjects);
} catch (e) {
alert("Error: " + e);
}
}

window.chrome.webview.addEventListener('message', async (arg) => {
console.log(arg);
native2webResult.innerHTML = "Expected: 2, Received: " + arg.additionalObjects.length;
const dirHandle = arg.additionalObjects[0];
const permission = await dirHandle.requestPermission({ mode: "readwrite" });
console.log("permission " + permission);
console.log("dirHandle " + dirHandle.name);

//try to write file
const fileHandle = await dirHandle.getFileHandle("temp.bin", { create: true });
const writable = await fileHandle.createWritable();
await writable.close();
});
</script>
</body>
</html>