Skip to content

Commit 02a1ccb

Browse files
peiche-jessicaWebView2GithubBot
andauthoredJun 19, 2024··
Update projects to use latest WebView2 SDK 1.0.2646-prerelease (#247)
* Updates for Win32, WPF, WinForms, UWP and WinUI3 sample apps from 128.0.2646.0 * Updated package version for Win32, WPF and WinForms sample apps to 1.0.2646-prerelease --------- Co-authored-by: WebView2 Github Bot <[email protected]>
1 parent 906135e commit 02a1ccb

16 files changed

+697
-25
lines changed
 

‎SampleApps/WebView2APISample/AppWindow.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@
4545
#include "ScenarioNotificationReceived.h"
4646
#include "ScenarioPermissionManagement.h"
4747
#include "ScenarioSaveAs.h"
48+
#include "ScenarioScreenCapture.h"
4849
#include "ScenarioSharedBuffer.h"
4950
#include "ScenarioSharedWorkerWRR.h"
51+
#include "ScenarioFileTypePolicy.h"
5052
#include "ScenarioVirtualHostMappingForPopUpWindow.h"
5153
#include "ScenarioVirtualHostMappingForSW.h"
5254
#include "ScenarioWebMessage.h"
@@ -665,6 +667,16 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam)
665667
NewComponent<ScenarioAcceleratorKeyPressed>(this);
666668
return true;
667669
}
670+
case IDM_SCENARIO_SCREEN_CAPTURE:
671+
{
672+
NewComponent<ScenarioScreenCapture>(this);
673+
return true;
674+
}
675+
case IDM_SCENARIO_FILE_TYPE_POLICY:
676+
{
677+
NewComponent<ScenarioFileTypePolicy>(this);
678+
return true;
679+
}
668680
}
669681
return false;
670682
}

‎SampleApps/WebView2APISample/ScenarioFileSystemHandleShare.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static constexpr WCHAR c_samplePath[] = L"ScenarioFileSystemHandleShare.html";
1616

1717
extern wil::unique_bstr GetDomainOfUri(PWSTR uri);
1818

19+
//! [PostWebMessageWithAdditionalObjects]
1920
ScenarioFileSystemHandleShare::ScenarioFileSystemHandleShare(AppWindow* appWindow)
2021
: m_appWindow(appWindow)
2122
{
@@ -29,25 +30,23 @@ ScenarioFileSystemHandleShare::ScenarioFileSystemHandleShare(AppWindow* appWindo
2930
ICoreWebView2* sender,
3031
ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT
3132
{
32-
wil::com_ptr<ICoreWebView2Experimental24> webview24 =
33-
m_webView.try_query<ICoreWebView2Experimental24>();
34-
CHECK_FEATURE_RETURN_HRESULT(webview24);
33+
wil::com_ptr<ICoreWebView2_23> webview23 =
34+
m_webView.try_query<ICoreWebView2_23>();
35+
CHECK_FEATURE_RETURN_HRESULT(webview23);
3536
wil::com_ptr<ICoreWebView2Environment> environment =
3637
appWindow->GetWebViewEnvironment();
37-
wil::com_ptr<ICoreWebView2ExperimentalEnvironment14>
38-
environment_experimental14 =
39-
environment.try_query<ICoreWebView2ExperimentalEnvironment14>();
40-
CHECK_FEATURE_RETURN_HRESULT(environment_experimental14);
41-
wil::com_ptr<ICoreWebView2ExperimentalFileSystemHandle> rootHandle;
42-
CHECK_FAILURE(environment_experimental14->CreateWebFileSystemDirectoryHandle(
38+
wil::com_ptr<ICoreWebView2Environment14>
39+
environment14 =
40+
environment.try_query<ICoreWebView2Environment14>();
41+
CHECK_FEATURE_RETURN_HRESULT(environment14);
42+
wil::com_ptr<ICoreWebView2FileSystemHandle> rootHandle;
43+
CHECK_FAILURE(environment14->CreateWebFileSystemDirectoryHandle(
4344
L"C:\\", COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY,
4445
&rootHandle));
45-
wil::com_ptr<ICoreWebView2ExperimentalObjectCollection> webObjectCollection;
46+
wil::com_ptr<ICoreWebView2ObjectCollection> webObjectCollection;
4647
IUnknown* webObjects[] = {rootHandle.get()};
47-
CHECK_FAILURE(environment_experimental14->CreateObjectCollection(
48+
CHECK_FAILURE(environment14->CreateObjectCollection(
4849
ARRAYSIZE(webObjects), webObjects, &webObjectCollection));
49-
wil::com_ptr<ICoreWebView2ObjectCollectionView> webObjectCollectionView =
50-
webObjectCollection.try_query<ICoreWebView2ObjectCollectionView>();
5150
wil::unique_cotaskmem_string source;
5251
CHECK_FAILURE(m_webView->get_Source(&source));
5352

@@ -57,16 +56,17 @@ ScenarioFileSystemHandleShare::ScenarioFileSystemHandleShare(AppWindow* appWindo
5756
// Check the source to ensure the message is sent to the correct target content.
5857
if (std::wstring(expectedDomain) == sourceDomain.get())
5958
{
60-
CHECK_FAILURE(webview24->PostWebMessageAsJsonWithAdditionalObjects(
59+
CHECK_FAILURE(webview23->PostWebMessageAsJsonWithAdditionalObjects(
6160
L"{ \"messageType\" : \"RootDirectoryHandle\" }",
62-
webObjectCollectionView.get()));
61+
webObjectCollection.get()));
6362
}
6463

6564
return S_OK;
6665
})
6766
.Get(),
6867
&m_navigationCompletedToken));
6968
}
69+
//! [PostWebMessageWithAdditionalObjects]
7070

7171
ScenarioFileSystemHandleShare::~ScenarioFileSystemHandleShare()
7272
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (C) Microsoft Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "stdafx.h"
6+
7+
#include "AppWindow.h"
8+
#include "CheckFailure.h"
9+
#include "ScenarioFileTypePolicy.h"
10+
11+
using namespace Microsoft::WRL;
12+
13+
static constexpr WCHAR c_samplePath[] = L"SecnarioFileTypePolicy.html";
14+
15+
ScenarioFileTypePolicy::ScenarioFileTypePolicy(AppWindow* appWindow)
16+
: m_appWindow(appWindow), m_webView2(appWindow->GetWebView())
17+
{
18+
if (m_webView2)
19+
{
20+
m_webView2Experimental27 = m_webView2.try_query<ICoreWebView2Experimental27>();
21+
m_webView2_2 = m_webView2.try_query<ICoreWebView2_2>();
22+
23+
m_sampleUri = m_appWindow->GetLocalUri(c_samplePath);
24+
CHECK_FAILURE(m_webView2->Navigate(m_sampleUri.c_str()));
25+
SuppressPolicyForExtension();
26+
27+
// Turn off this scenario if we navigate away from the demo page.
28+
CHECK_FAILURE(m_webView2_2->add_DOMContentLoaded(
29+
Callback<ICoreWebView2DOMContentLoadedEventHandler>(
30+
[this](ICoreWebView2* sender, ICoreWebView2DOMContentLoadedEventArgs* args)
31+
-> HRESULT
32+
{
33+
wil::unique_cotaskmem_string uri;
34+
sender->get_Source(&uri);
35+
if (uri.get() != m_sampleUri)
36+
m_appWindow->DeleteComponent(this);
37+
return S_OK;
38+
})
39+
.Get(),
40+
&m_DOMcontentLoadedToken));
41+
}
42+
}
43+
44+
//! [SuppressPolicyForExtension]
45+
// This example will register the event with two custom rules.
46+
// 1. Suppressing file type policy, security dialog, and allows saving ".eml" files
47+
// directly.
48+
// 2. When the URI is trusted.- Showing customized warning UI when saving ".iso"
49+
// files. It allows to block the saving directly.
50+
bool ScenarioFileTypePolicy::SuppressPolicyForExtension()
51+
{
52+
if (!m_webView2Experimental27)
53+
return false;
54+
m_webView2Experimental27->add_SaveFileSecurityCheckStarting(
55+
Callback<ICoreWebView2ExperimentalSaveFileSecurityCheckStartingEventHandler>(
56+
[this](
57+
ICoreWebView2* sender,
58+
ICoreWebView2ExperimentalSaveFileSecurityCheckStartingEventArgs* args)
59+
-> HRESULT
60+
{
61+
// Get the file extension for file to be saved.
62+
// And convert the extension to lower case for a
63+
// case-insensitive comparasion.
64+
wil::unique_cotaskmem_string extension;
65+
CHECK_FAILURE(args->get_FileExtension(&extension));
66+
std::wstring extension_lower = extension.get();
67+
std::transform(
68+
extension_lower.begin(), extension_lower.end(), extension_lower.begin(),
69+
::towlower);
70+
71+
// Suppress default policy for ".eml" file.
72+
if (wcscmp(extension_lower.c_str(), L".eml") == 0)
73+
{
74+
CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE));
75+
}
76+
77+
// Cancel save/download for ".iso" file.
78+
if (wcscmp(extension_lower.c_str(), L".iso") == 0)
79+
{
80+
wil::com_ptr<ICoreWebView2Deferral> deferral;
81+
CHECK_FAILURE(args->GetDeferral(&deferral));
82+
83+
m_appWindow->RunAsync(
84+
[this, args = wil::make_com_ptr(args), deferral]()
85+
{
86+
// With the deferral, the cancel decision and
87+
// message box can be replaced with a customized UI.
88+
CHECK_FAILURE(args->put_CancelSave(TRUE));
89+
MessageBox(
90+
m_appWindow->GetMainWindow(), L"The saving has been blocked",
91+
L"Info", MB_OK);
92+
CHECK_FAILURE(deferral->Complete());
93+
});
94+
}
95+
return S_OK;
96+
})
97+
.Get(),
98+
&m_saveFileSecurityCheckStartingToken);
99+
100+
MessageBox(
101+
m_appWindow->GetMainWindow(),
102+
(L"Example rules of Dangerous File Security Policy has been applied in this demo page"),
103+
L"Info", MB_OK);
104+
return true;
105+
}
106+
//! [SuppressPolicyForExtension]
107+
108+
ScenarioFileTypePolicy::~ScenarioFileTypePolicy()
109+
{
110+
if (m_webView2Experimental27)
111+
{
112+
CHECK_FAILURE(m_webView2Experimental27->remove_SaveFileSecurityCheckStarting(
113+
m_saveFileSecurityCheckStartingToken));
114+
}
115+
CHECK_FAILURE(m_webView2_2->remove_DOMContentLoaded(m_DOMcontentLoadedToken));
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (C) Microsoft Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "stdafx.h"
6+
7+
#include <string>
8+
9+
#include "AppWindow.h"
10+
#include "ComponentBase.h"
11+
12+
class ScenarioFileTypePolicy : public ComponentBase
13+
{
14+
public:
15+
ScenarioFileTypePolicy(AppWindow* appWindow);
16+
~ScenarioFileTypePolicy();
17+
18+
private:
19+
bool SuppressPolicyForExtension();
20+
21+
AppWindow* m_appWindow;
22+
wil::com_ptr<ICoreWebView2> m_webView2;
23+
wil::com_ptr<ICoreWebView2_2> m_webView2_2;
24+
wil::com_ptr<ICoreWebView2Experimental27> m_webView2Experimental27;
25+
EventRegistrationToken m_saveFileSecurityCheckStartingToken = {};
26+
EventRegistrationToken m_DOMcontentLoadedToken = {};
27+
std::wstring m_sampleUri;
28+
};

‎SampleApps/WebView2APISample/ScenarioScreenCapture.cpp

+248
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,251 @@
1010
#include "CheckFailure.h"
1111

1212
using namespace Microsoft::WRL;
13+
14+
static constexpr WCHAR c_samplePath[] = L"ScenarioScreenCapture.html";
15+
16+
ScenarioScreenCapture::ScenarioScreenCapture(AppWindow* appWindow)
17+
: m_appWindow(appWindow), m_webView(appWindow->GetWebView())
18+
{
19+
m_sampleUri = m_appWindow->GetLocalUri(c_samplePath);
20+
21+
//! [ScreenCaptureStarting0]
22+
m_webViewExperimental26 = m_webView.try_query<ICoreWebView2Experimental26>();
23+
if (m_webViewExperimental26)
24+
{
25+
m_webViewExperimental26->add_ScreenCaptureStarting(
26+
Callback<ICoreWebView2ExperimentalScreenCaptureStartingEventHandler>(
27+
[this](
28+
ICoreWebView2* sender,
29+
ICoreWebView2ExperimentalScreenCaptureStartingEventArgs* args) -> HRESULT
30+
{
31+
// Get Frame Info
32+
wil::com_ptr<ICoreWebView2FrameInfo> frameInfo;
33+
CHECK_FAILURE(args->get_OriginalSourceFrameInfo(&frameInfo));
34+
35+
wil::com_ptr<ICoreWebView2FrameInfo2> frameInfo2;
36+
CHECK_FAILURE(frameInfo->QueryInterface(IID_PPV_ARGS(&frameInfo2)));
37+
38+
UINT32 source_frameId;
39+
CHECK_FAILURE(frameInfo2->get_FrameId(&source_frameId));
40+
41+
BOOL cancel = m_mainFramePermission == FALSE;
42+
CHECK_FAILURE(args->put_Cancel(cancel));
43+
return S_OK;
44+
})
45+
.Get(),
46+
&m_screenCaptureStartingToken);
47+
}
48+
//! [ScreenCaptureStarting0]
49+
50+
//! [ScreenCaptureStarting1]
51+
m_webView4 = m_webView.try_query<ICoreWebView2_4>();
52+
if (m_webView4)
53+
{
54+
CHECK_FAILURE(m_webView4->add_FrameCreated(
55+
Callback<ICoreWebView2FrameCreatedEventHandler>(
56+
[this](
57+
ICoreWebView2* sender, ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT
58+
{
59+
wil::com_ptr<ICoreWebView2Frame> webviewFrame;
60+
CHECK_FAILURE(args->get_Frame(&webviewFrame));
61+
62+
auto frame5 = webviewFrame.try_query<ICoreWebView2Frame5>();
63+
64+
UINT32 frameId;
65+
frame5->get_FrameId(&frameId);
66+
67+
m_screenCaptureFrameIdPermission[frameId] = TRUE;
68+
69+
wil::com_ptr<ICoreWebView2Frame2> webviewFrame2 =
70+
webviewFrame.try_query<ICoreWebView2Frame2>();
71+
if (!webviewFrame2)
72+
{
73+
return S_OK;
74+
}
75+
76+
bool cancel_on_frame = false;
77+
78+
CHECK_FAILURE(webviewFrame2->add_WebMessageReceived(
79+
Microsoft::WRL::Callback<
80+
ICoreWebView2FrameWebMessageReceivedEventHandler>(
81+
[this, frameId](
82+
ICoreWebView2Frame* sender,
83+
ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
84+
{
85+
BOOL cancel = false;
86+
87+
wil::unique_cotaskmem_string messageRaw;
88+
HRESULT hr = args->TryGetWebMessageAsString(&messageRaw);
89+
if (hr == E_INVALIDARG)
90+
{
91+
// Was not a string message. Ignore.
92+
return hr;
93+
}
94+
// Any other problems are fatal.
95+
CHECK_FAILURE(hr);
96+
std::wstring message = messageRaw.get();
97+
98+
if (message == L"EnableScreenCapture")
99+
{
100+
cancel = false;
101+
}
102+
else if (message == L"DisableScreenCapture")
103+
{
104+
cancel = true;
105+
}
106+
else
107+
{
108+
// Ignore unrecognized messages, but log for further
109+
// investigation since it suggests a mismatch between the
110+
// web content and the host.
111+
OutputDebugString(
112+
std::wstring(
113+
L"Unexpected message from main page:" + message)
114+
.c_str());
115+
}
116+
117+
m_screenCaptureFrameIdPermission[frameId] = (cancel == FALSE);
118+
119+
return S_OK;
120+
})
121+
.Get(),
122+
nullptr));
123+
124+
m_experimentalFrame6 =
125+
webviewFrame.try_query<ICoreWebView2ExperimentalFrame6>();
126+
127+
m_experimentalFrame6->add_ScreenCaptureStarting(
128+
Callback<
129+
ICoreWebView2ExperimentalFrameScreenCaptureStartingEventHandler>(
130+
[this](
131+
ICoreWebView2Frame* sender,
132+
ICoreWebView2ExperimentalScreenCaptureStartingEventArgs* args)
133+
-> HRESULT
134+
{
135+
args->put_Handled(TRUE);
136+
137+
bool cancel = FALSE;
138+
139+
// Get Frame Info
140+
wil::com_ptr<ICoreWebView2FrameInfo> frameInfo;
141+
CHECK_FAILURE(args->get_OriginalSourceFrameInfo(&frameInfo));
142+
143+
wil::com_ptr<ICoreWebView2FrameInfo2> frameInfo2;
144+
CHECK_FAILURE(
145+
frameInfo->QueryInterface(IID_PPV_ARGS(&frameInfo2)));
146+
147+
// Frame Source
148+
wil::unique_cotaskmem_string frameSource;
149+
CHECK_FAILURE(frameInfo->get_Source(&frameSource));
150+
151+
UINT32 source_frameId;
152+
CHECK_FAILURE(frameInfo2->get_FrameId(&source_frameId));
153+
154+
cancel =
155+
(m_screenCaptureFrameIdPermission[source_frameId] == FALSE);
156+
157+
CHECK_FAILURE(args->put_Cancel(cancel));
158+
return S_OK;
159+
})
160+
.Get(),
161+
&m_frameScreenCaptureStartingToken);
162+
163+
return S_OK;
164+
})
165+
.Get(),
166+
&m_frameCreatedToken));
167+
}
168+
else
169+
{
170+
FeatureNotAvailable();
171+
}
172+
//! [ScreenCaptureStarting1]
173+
174+
// Turn off this scenario if we navigate away from the sample page
175+
CHECK_FAILURE(m_webView->add_ContentLoading(
176+
Callback<ICoreWebView2ContentLoadingEventHandler>(
177+
[this](ICoreWebView2* sender, ICoreWebView2ContentLoadingEventArgs* args) -> HRESULT
178+
{
179+
wil::unique_cotaskmem_string uri;
180+
sender->get_Source(&uri);
181+
if (uri.get() != m_sampleUri)
182+
{
183+
m_appWindow->DeleteComponent(this);
184+
}
185+
return S_OK;
186+
})
187+
.Get(),
188+
&m_contentLoadingToken));
189+
190+
CHECK_FAILURE(m_webView->add_WebMessageReceived(
191+
Microsoft::WRL::Callback<ICoreWebView2WebMessageReceivedEventHandler>(
192+
[this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
193+
-> HRESULT
194+
{
195+
BOOL cancel = FALSE;
196+
wil::unique_cotaskmem_string uri;
197+
CHECK_FAILURE(args->get_Source(&uri));
198+
199+
// Always validate that the origin of the message is what you
200+
// expect.
201+
if (uri.get() != m_sampleUri)
202+
{
203+
// Ignore messages from untrusted sources.
204+
return E_INVALIDARG;
205+
}
206+
wil::unique_cotaskmem_string messageRaw;
207+
HRESULT hr = args->TryGetWebMessageAsString(&messageRaw);
208+
if (hr == E_INVALIDARG)
209+
{
210+
// Was not a string message. Ignore.
211+
return hr;
212+
}
213+
// Any other problems are fatal.
214+
CHECK_FAILURE(hr);
215+
std::wstring message = messageRaw.get();
216+
217+
if (message == L"EnableScreenCapture")
218+
{
219+
cancel = FALSE;
220+
}
221+
else if (message == L"DisableScreenCapture")
222+
{
223+
cancel = TRUE;
224+
}
225+
else
226+
{
227+
// Ignore unrecognized messages, but log for further
228+
// investigation since it suggests a mismatch between the
229+
// web content and the host.
230+
OutputDebugString(
231+
std::wstring(L"Unexpected message from main page:" + message).c_str());
232+
}
233+
m_mainFramePermission = (cancel == FALSE);
234+
return S_OK;
235+
})
236+
.Get(),
237+
&m_webMessageReceivedToken));
238+
239+
CHECK_FAILURE(m_webView->Navigate(m_sampleUri.c_str()));
240+
}
241+
242+
ScenarioScreenCapture::~ScenarioScreenCapture()
243+
{
244+
m_webView->remove_ContentLoading(m_contentLoadingToken);
245+
m_webView->remove_WebMessageReceived(m_webMessageReceivedToken);
246+
if (m_webViewExperimental26)
247+
{
248+
CHECK_FAILURE(m_webViewExperimental26->remove_ScreenCaptureStarting(
249+
m_screenCaptureStartingToken));
250+
}
251+
if (m_experimentalFrame6)
252+
{
253+
CHECK_FAILURE(m_experimentalFrame6->remove_ScreenCaptureStarting(
254+
m_frameScreenCaptureStartingToken));
255+
}
256+
if (m_webView4)
257+
{
258+
CHECK_FAILURE(m_webView4->remove_FrameCreated(m_frameCreatedToken));
259+
}
260+
}

‎SampleApps/WebView2APISample/ScenarioScreenCapture.h

+22
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,25 @@
99

1010
#include "AppWindow.h"
1111
#include "ComponentBase.h"
12+
13+
class ScenarioScreenCapture : public ComponentBase
14+
{
15+
public:
16+
ScenarioScreenCapture(AppWindow* appWindow);
17+
~ScenarioScreenCapture() override;
18+
19+
private:
20+
AppWindow* m_appWindow = nullptr;
21+
wil::com_ptr<ICoreWebView2> m_webView;
22+
wil::com_ptr<ICoreWebView2_4> m_webView4;
23+
wil::com_ptr<ICoreWebView2Experimental26> m_webViewExperimental26;
24+
wil::com_ptr<ICoreWebView2ExperimentalFrame6> m_experimentalFrame6;
25+
std::wstring m_sampleUri;
26+
std::map<int, BOOL> m_screenCaptureFrameIdPermission;
27+
BOOL m_mainFramePermission = TRUE;
28+
EventRegistrationToken m_contentLoadingToken = {};
29+
EventRegistrationToken m_webMessageReceivedToken = {};
30+
EventRegistrationToken m_frameCreatedToken = {};
31+
EventRegistrationToken m_screenCaptureStartingToken = {};
32+
EventRegistrationToken m_frameScreenCaptureStartingToken = {};
33+
};

‎SampleApps/WebView2APISample/WebView2APISample.rc

+2
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ BEGIN
302302
MENUITEM "Programmatic Save As", IDM_SCENARIO_SAVE_AS_PROGRAMMATIC
303303
END
304304
MENUITEM "Accelerator Key Pressed", IDM_SCENARIO_ACCELERATOR_KEY_PRESSED
305+
MENUITEM "Screen Capture", IDM_SCENARIO_SCREEN_CAPTURE
306+
MENUITEM "File Type Policy", IDM_SCENARIO_FILE_TYPE_POLICY
305307
END
306308
POPUP "&Audio"
307309
BEGIN

‎SampleApps/WebView2APISample/WebView2APISample.vcxproj

+10-2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@
238238
<ClInclude Include="ScenarioDragDrop.h" />
239239
<ClInclude Include="ScenarioExtensionsManagement.h" />
240240
<ClInclude Include="ScenarioFileSystemHandleShare.h" />
241+
<ClInclude Include="ScenarioFileTypePolicy.h" />
241242
<ClInclude Include="ScenarioIFrameDevicePermission.h" />
242243
<ClInclude Include="ScenarioNavigateWithWebResourceRequest.h" />
243244
<ClInclude Include="ScenarioNonClientRegionSupport.h" />
@@ -290,6 +291,7 @@
290291
<ClCompile Include="ScenarioDragDrop.cpp" />
291292
<ClCompile Include="ScenarioExtensionsManagement.cpp" />
292293
<ClCompile Include="ScenarioFileSystemHandleShare.cpp" />
294+
<ClCompile Include="ScenarioFileTypePolicy.cpp" />
293295
<ClCompile Include="ScenarioIFrameDevicePermission.cpp" />
294296
<ClCompile Include="ScenarioNavigateWithWebResourceRequest.cpp" />
295297
<ClCompile Include="ScenarioNonClientRegionSupport.cpp" />
@@ -347,6 +349,9 @@
347349
<CopyFileToFolders Include="assets/extensions/example-devtools-extension/panel.js">
348350
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
349351
</CopyFileToFolders>
352+
<CopyFileToFolders Include="assets/LandingPageForFindDemo.html">
353+
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
354+
</CopyFileToFolders>
350355
<CopyFileToFolders Include="assets/ScenarioAcceleratorKeyPressed.html">
351356
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
352357
</CopyFileToFolders>
@@ -407,6 +412,9 @@
407412
<CopyFileToFolders Include="assets/ScenarioThrottlingControlMonitor.js">
408413
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
409414
</CopyFileToFolders>
415+
<CopyFileToFolders Include="assets/SecnarioFileTypePolicy.html">
416+
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
417+
</CopyFileToFolders>
410418
<CopyFileToFolders Include="assets/sw_scope/cached_by_sw_install.jpg">
411419
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
412420
</CopyFileToFolders>
@@ -472,13 +480,13 @@
472480
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
473481
<ImportGroup Label="ExtensionTargets">
474482
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
475-
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.2584-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.2584-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
483+
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.2646-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.2646-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
476484
</ImportGroup>
477485
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
478486
<PropertyGroup>
479487
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
480488
</PropertyGroup>
481489
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
482-
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.2584-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.2584-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
490+
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.2646-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.2646-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
483491
</Target>
484492
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<title>Demo: Programmatic Find API</title>
6+
<style>
7+
body {
8+
font-family: Arial, sans-serif;
9+
margin: 20px;
10+
}
11+
header {
12+
background-color: #f1f1f1;
13+
padding: 20px;
14+
text-align: center;
15+
}
16+
footer {
17+
background-color: #f1f1f1;
18+
padding: 10px;
19+
text-align: center;
20+
}
21+
h1, h2, h3 {
22+
color: #333366;
23+
}
24+
p {
25+
text-align: justify;
26+
}
27+
</style>
28+
</head>
29+
<body>
30+
31+
<header>
32+
<h1>Programmatic Find API Demo</h1>
33+
</header>
34+
35+
<h2>Introduction</h2>
36+
<p>Welcome to this demo showcasing the capabilities of the Programmatic Find API with WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 WebView2 . We have designed this feature to make it easier for developers to programmatically access and utilize WebView2's finding capabilities.</p>
37+
38+
<h2>Why Programmatic Find API?</h2>
39+
<p>Programmatic Find API offers a way to embed WebView2's finding functionality directly into your applications. This enhances the overall user experience by allowing for customized behavior and extended functionalities.</p>
40+
41+
<h3>Features</h3>
42+
<ul>
43+
<li>Programmatic Access</li>
44+
<li>Automated Testing Support</li>
45+
<li>Real-time Results with WebView2</li>
46+
<li>Enhanced Customization</li>
47+
</ul>
48+
49+
<h2>Use Cases</h2>
50+
<p>Some common use cases include text highlighting, real-time search features, and quality assurance testing. This ensures that applications built with WebView2 can offer a more dynamic and interactive experience.</p>
51+
52+
<h3>Technical Aspects</h3>
53+
<p>The API is designed to be platform-agnostic, allowing developers to implement WebView2-based functionalities across a variety of platforms. It is also built to be backward-compatible, ensuring a smooth transition for applications relying on older versions of WebView2.</p>
54+
55+
<h2>Conclusion</h2>
56+
<p>We hope this demo helps you understand the advantages of using the Programmatic Find API in your WebView2-based applications. The aim is to make your development process smoother while enhancing the user experience.</p>
57+
58+
<h2>FAQs</h2>
59+
<ol>
60+
<li>Is this feature limited to any specific programming languages?</li>
61+
<li>How can I customize the search experience in WebView2?</li>
62+
<li>What platforms currently support this WebView2 feature?</li>
63+
</ol>
64+
65+
<footer>
66+
<p>For more information, please visit the official WebView2 documentation. https://learn.microsoft.com/en-us/microsoft-edge/webview2/?form=MA13LH </p>
67+
</footer>
68+
69+
</body>
70+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>ScenarioFileTypePolicy</title>
5+
<script>
6+
document.addEventListener('DOMContentLoaded', () => {
7+
async function saveFile() {
8+
let ext = document.getElementById("extensionText");
9+
// Show the save file picker
10+
const newHandle = await window.showSaveFilePicker({suggestedName:`sample_file.${ext.value}`});
11+
12+
// Write the content to the selected file
13+
const writable = await newHandle.createWritable();
14+
await writable.write("sample sentence");
15+
await writable.close();
16+
}
17+
document.getElementById('showSaveFilePickerButton').addEventListener('click', saveFile);
18+
});
19+
</script>
20+
</head>
21+
<body>
22+
<h1>File Type Policy API Demo Page</h1>
23+
<p>Two customized example rules in this demo:</p>
24+
<p>1. Smoothly save *.eml file without file extension warning</p>
25+
<p>2. Intentionally block save *.iso file</p>
26+
<p>Please enter a file extension: <input type="text" id="extensionText" placeholder="try eml or iso" />
27+
<button id="showSaveFilePickerButton">save</button></p>
28+
<br>
29+
</body>
30+
</html>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="Microsoft.Web.WebView2" version="1.0.2584-prerelease" targetFramework="native" />
3+
<package id="Microsoft.Web.WebView2" version="1.0.2646-prerelease" targetFramework="native" />
44
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" />
55
</packages>

‎SampleApps/WebView2APISample/resource.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
#define IDM_SCENARIO_SAVE_AS_TOGGLE_SILENT 2040
187187
#define IDM_SCENARIO_SAVE_AS_PROGRAMMATIC 2041
188188
#define IDM_SCENARIO_ACCELERATOR_KEY_PRESSED 2042
189+
#define IDM_SCENARIO_FILE_TYPE_POLICY 2049
189190
#define IDM_CREATION_MODE_WINDOWED 3000
190191
#define IDM_CREATION_MODE_VISUAL_DCOMP 3001
191192
#define IDM_CREATION_MODE_TARGET_DCOMP 3002
@@ -224,14 +225,15 @@
224225
#define IDC_CHECK_USE_OS_REGION 32803
225226
#define ID_CUSTOM_DATA_PARTITION 32804
226227
#define ID_SETTINGS_NON_CLIENT_REGION_SUPPORT_ENABLED 32805
228+
#define IDM_SCENARIO_SCREEN_CAPTURE 32809
227229
#define IDC_STATIC -1
228230
// Next default values for new objects
229231
//
230232
#ifdef APSTUDIO_INVOKED
231233
#ifndef APSTUDIO_READONLY_SYMBOLS
232234
#define _APS_NO_MFC 1
233235
#define _APS_NEXT_RESOURCE_VALUE 245
234-
#define _APS_NEXT_COMMAND_VALUE 32806
236+
#define _APS_NEXT_COMMAND_VALUE 32810
235237
#define _APS_NEXT_CONTROL_VALUE 1015
236238
#define _APS_NEXT_SYMED_VALUE 110
237239
#endif

‎SampleApps/WebView2WindowsFormsBrowser/WebView2WindowsFormsBrowser.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<PlatformTarget>AnyCPU</PlatformTarget>
2626
</PropertyGroup>
2727
<ItemGroup>
28-
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2584-prerelease" />
28+
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2646-prerelease" />
2929
</ItemGroup>
3030
<ItemGroup>
3131
<Folder Include="assets\" />

‎SampleApps/WebView2WpfBrowser/MainWindow.xaml

+9
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,13 @@ found in the LICENSE file.
9797
<CommandBinding Command="{x:Static local:MainWindow.NewWebViewCommand}" Executed="NewWebViewCommandExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
9898

9999
<CommandBinding Command="{x:Static local:MainWindow.PermissionManagementCommand}" Executed="PermissionManagementExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
100+
<CommandBinding Command="{x:Static local:MainWindow.NonClientRegionSupportCommand}" Executed="NonClientRegionSupportCmdExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
101+
<CommandBinding Command="{x:Static local:MainWindow.NonClientRegionSupportEnabledCommand}" Executed="NonClientRegionSupportEnabledCmdExecuted"
102+
CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
100103
<CommandBinding Command="{x:Static local:MainWindow.NotificationReceivedCommand}" Executed="NotificationReceivedExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
101104
<CommandBinding Command="{x:Static local:MainWindow.FileExplorerCommand}" Executed="FileExplorerExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
105+
<CommandBinding Command="{x:Static local:MainWindow.ToggleScreenCaptureEnableCommand}" Executed="TogglScreenCaptureEnabledCmdExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
106+
<CommandBinding Command="{x:Static local:MainWindow.FileTypePolicyCommand}" Executed="FileTypePolicyExecuted" CanExecute="CoreWebView2RequiringCmdsCanExecute"/>
102107
</Window.CommandBindings>
103108
<DockPanel>
104109
<Menu DockPanel.Dock="Top">
@@ -165,6 +170,7 @@ found in the LICENSE file.
165170
<MenuItem Header="_Balanced" Command="{x:Static local:MainWindow.TrackingPreventionLevelCommand}" CommandParameter="Balanced"/>
166171
<MenuItem Header="_Strict" Command="{x:Static local:MainWindow.TrackingPreventionLevelCommand}" CommandParameter="Strict"/>
167172
</MenuItem>
173+
<MenuItem Header="Toggle Non-Client Region Support" Command="{x:Static local:MainWindow.NonClientRegionSupportCommand}"/>
168174
</MenuItem>
169175
<MenuItem Header="_View">
170176
<MenuItem Header="Toggle _Visibility" Name="webViewVisible" IsCheckable="True" IsChecked="True"/>
@@ -225,8 +231,11 @@ found in the LICENSE file.
225231
<MenuItem Header="_Web Messages" Command="{x:Static local:MainWindow.WebMessagesCommand}"/>
226232
<MenuItem Header="_Shared Buffer" Command="{x:Static local:MainWindow.SharedBufferRequestedCommand}"/>
227233
<MenuItem Header="Permission Management" Command="{x:Static local:MainWindow.PermissionManagementCommand}"/>
234+
<MenuItem Header="_Non-Client Region Support" Command="{x:Static local:MainWindow.NonClientRegionSupportEnabledCommand}"/>
228235
<MenuItem Header="Notification Received" Command="{x:Static local:MainWindow.NotificationReceivedCommand}"/>
229236
<MenuItem Header="File-system explorer" Command="{x:Static local:MainWindow.FileExplorerCommand}"/>
237+
<MenuItem Header="Toggle Screen Capture" Command="{x:Static local:MainWindow.ToggleScreenCaptureEnableCommand}"/>
238+
<MenuItem Header="File Type Policy" Command="{x:Static local:MainWindow.FileTypePolicyCommand}"/>
230239
</MenuItem>
231240
<MenuItem Header="_Audio">
232241
<MenuItem Header="Toggle Mute State" IsCheckable="True" IsChecked="False" Command="{x:Static local:MainWindow.ToggleMuteStateCommand}"/>

‎SampleApps/WebView2WpfBrowser/MainWindow.xaml.cs

+129-4
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ public partial class MainWindow : Window
119119
public static RoutedCommand ToggleSilentCommand = new RoutedCommand();
120120
public static RoutedCommand ThrottlingControlCommand = new RoutedCommand();
121121
public static RoutedCommand FileExplorerCommand = new RoutedCommand();
122+
public static RoutedCommand ToggleScreenCaptureEnableCommand = new RoutedCommand();
123+
public static RoutedCommand FileTypePolicyCommand = new RoutedCommand();
122124

123125
#endregion commands
124126

@@ -1304,16 +1306,54 @@ void DeleteProfileExecuted(object target, ExecutedRoutedEventArgs e)
13041306

13051307
void NonClientRegionSupportCmdExecuted(object target, ExecutedRoutedEventArgs e)
13061308
{
1309+
try
1310+
{
1311+
// <ToggleNonClientSupportEnabled>
1312+
WebViewSettings.IsNonClientRegionSupportEnabled =
1313+
!WebViewSettings.IsNonClientRegionSupportEnabled;
1314+
// </ToggleNonClientSupportEnabled>
1315+
MessageBox.Show("Non-client region support will be " +
1316+
(WebViewSettings.IsNonClientRegionSupportEnabled ?
1317+
"enabled " : "disabled ") + "after the next navigation.");
1318+
}
1319+
catch (NotImplementedException exception)
1320+
{
1321+
MessageBox.Show(this, "Toggle Non-client region support failed: " +
1322+
exception.Message, "Non-client Support");
1323+
}
13071324
}
1325+
13081326
void NonClientRegionSupportEnabledCmdExecuted(object target, ExecutedRoutedEventArgs e)
13091327
{
1328+
webView.CoreWebView2.NavigationStarting += WebView_NavigationStartingNonClientRegionSupport;
1329+
webView.CoreWebView2.DOMContentLoaded += WebView_DOMContentLoadedNonClientRegionSupport;
1330+
1331+
webView.Source = new Uri("https://appassets.example/ScenarioNonClientRegionSupport.html");
13101332
}
1333+
13111334
void WebView_DOMContentLoadedNonClientRegionSupport(object sender, CoreWebView2DOMContentLoadedEventArgs e)
13121335
{
1336+
if (webView.CoreWebView2.Source != "https://appassets.example/ScenarioNonClientRegionSupport.html")
1337+
{
1338+
webView.CoreWebView2.NavigationStarting -= WebView_NavigationStartingNonClientRegionSupport;
1339+
webView.CoreWebView2.DOMContentLoaded -= WebView_DOMContentLoadedNonClientRegionSupport;
1340+
}
13131341
}
1342+
13141343
void WebView_NavigationStartingNonClientRegionSupport(object sender, CoreWebView2NavigationStartingEventArgs e)
13151344
{
1345+
if (e.Uri == "https://appassets.example/ScenarioNonClientRegionSupport.html"
1346+
&& !WebViewSettings.IsNonClientRegionSupportEnabled)
1347+
{
1348+
WebViewSettings.IsNonClientRegionSupportEnabled = true;
1349+
}
1350+
else if (e.Uri != "https://appassets.example/ScenarioNonClientRegionSupport.html"
1351+
&& WebViewSettings.IsNonClientRegionSupportEnabled)
1352+
{
1353+
WebViewSettings.IsNonClientRegionSupportEnabled = false;
1354+
}
13161355
}
1356+
13171357
void PdfToolbarSaveCmdExecuted(object target, ExecutedRoutedEventArgs e)
13181358
{
13191359
// <ToggleHiddenPdfToolbarItems>
@@ -2022,6 +2062,10 @@ void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2Init
20222062
webView.CoreWebView2.DOMContentLoaded += WebView_PermissionManager_DOMContentLoaded;
20232063
webView.CoreWebView2.WebMessageReceived += WebView_PermissionManager_WebMessageReceived;
20242064

2065+
#if USE_WEBVIEW2_EXPERIMENTAL
2066+
webView.CoreWebView2.ScreenCaptureStarting += WebView_ScreenCaptureStarting;
2067+
#endif
2068+
20252069
// The CoreWebView2Environment instance is reused when re-assigning CoreWebView2CreationProperties
20262070
// to the replacement control. We don't need to re-attach the event handlers unless the environment
20272071
// instance has changed.
@@ -3397,26 +3441,107 @@ string GetJSONStringField(string jsonMessage, string fieldName)
33973441

33983442
void FileExplorerExecuted(object target, ExecutedRoutedEventArgs e)
33993443
{
3400-
#if USE_WEBVIEW2_EXPERIMENTAL
34013444
webView.CoreWebView2.NavigationCompleted += delegate (
34023445
object webview2, CoreWebView2NavigationCompletedEventArgs args)
34033446
{
34043447
if (args.IsSuccess && webView.CoreWebView2.Source.Equals("https://appassets.example/ScenarioFileSystemHandleShare.html"))
34053448
{
3406-
webView.CoreWebView2.PostWebMessageAsJsonWithAdditionalObjects("{ \"messageType\" : \"RootDirectoryHandle\" }", new List<object>()
3449+
webView.CoreWebView2.PostWebMessageAsJson("{ \"messageType\" : \"RootDirectoryHandle\" }", new List<object>()
34073450
{
34083451
webView.CoreWebView2.Environment.CreateWebFileSystemDirectoryHandle(
34093452
"C:\\",
34103453
CoreWebView2FileSystemHandlePermission.ReadOnly)
34113454
});
34123455
}
34133456
};
3414-
webView.Source = new Uri("https://appassets.example/ScenarioFileSystemHandleShare.html");
3415-
#endif
3457+
webView.Source = new Uri("https://appassets.example/ScenarioFileSystemHandleShare.html");
34163458
}
34173459

34183460
void ThrottlingControlExecuted(object target, ExecutedRoutedEventArgs e)
34193461
{
34203462
}
3463+
// <ScreenCaptureStarting0>
3464+
#if USE_WEBVIEW2_EXPERIMENTAL
3465+
private bool isScreenCaptureEnabled = true;
3466+
3467+
void WebView_ScreenCaptureStarting(object sender, CoreWebView2ScreenCaptureStartingEventArgs args)
3468+
{
3469+
// Get Frame Info
3470+
CoreWebView2FrameInfo frameInfo;
3471+
frameInfo = args.OriginalSourceFrameInfo;
3472+
3473+
// Frame Source
3474+
string frameSource;
3475+
frameSource = frameInfo.Source;
3476+
3477+
args.Cancel = !isScreenCaptureEnabled;
3478+
}
3479+
#endif
3480+
3481+
void TogglScreenCaptureEnabledCmdExecuted(object target, ExecutedRoutedEventArgs e)
3482+
{
3483+
#if USE_WEBVIEW2_EXPERIMENTAL
3484+
isScreenCaptureEnabled = !isScreenCaptureEnabled;
3485+
MessageBox.Show(isScreenCaptureEnabled ? "Screen Capture Enabled" : "Screen Capture Disabled", "Info");
3486+
#endif
3487+
}
3488+
3489+
// </ScreenCaptureStarting0>
3490+
// <FileTypePolicy>
3491+
void FileTypePolicyExecuted(object target, ExecutedRoutedEventArgs e)
3492+
{
3493+
#if USE_WEBVIEW2_EXPERIMENTAL
3494+
webView.CoreWebView2.SaveFileSecurityCheckStarting += WebView_SaveFileSecurityCheckStarting;
3495+
webView.CoreWebView2.DOMContentLoaded += WebView_FileTypePolicy_DOMContentLoaded;
3496+
webView.CoreWebView2.SetVirtualHostNameToFolderMapping(
3497+
"appassets.example", "assets", CoreWebView2HostResourceAccessKind.DenyCors);
3498+
webView.Source = new Uri("https://appassets.example/SecnarioFileTypePolicy.html");
3499+
MessageBox.Show("Example rules of Dangerous File Security Policy has been applied in this demo page",
3500+
"Info");
3501+
#endif
3502+
}
3503+
// </FileTypePolicy>
3504+
3505+
#if USE_WEBVIEW2_EXPERIMENTAL
3506+
// <SaveFileSecurityCheckStarting>
3507+
void WebView_SaveFileSecurityCheckStarting(object sender, CoreWebView2SaveFileSecurityCheckStartingEventArgs args)
3508+
{
3509+
3510+
// Suppress default policy for ".eml" file.
3511+
if (string.Equals(args.FileExtension, ".eml", StringComparison.OrdinalIgnoreCase))
3512+
{
3513+
args.SuppressDefaultPolicy = true;
3514+
}
3515+
3516+
// Cancel save/download for ".iso" file.
3517+
if (args.FileExtension == ".iso")
3518+
{
3519+
CoreWebView2Deferral deferral = args.GetDeferral();
3520+
System.Threading.SynchronizationContext.Current.Post((_) =>
3521+
{
3522+
using (deferral)
3523+
{
3524+
// With the deferral, the cancel decision and
3525+
// message box can be replaced with a customized UI.
3526+
args.CancelSave = true;
3527+
MessageBox.Show("The saving has been blocked", "Info");
3528+
}
3529+
}, null);
3530+
}
3531+
}
3532+
// </SaveFileSecurityCheckStarting>
3533+
3534+
void WebView_FileTypePolicy_DOMContentLoaded(object sender, CoreWebView2DOMContentLoadedEventArgs e)
3535+
{
3536+
// Turn off this scenario if we navigate away from the demo page.
3537+
if (webView.CoreWebView2.Source != "https://appassets.example/SecnarioFileTypePolicy.html")
3538+
{
3539+
webView.CoreWebView2.SaveFileSecurityCheckStarting -= WebView_SaveFileSecurityCheckStarting;
3540+
webView.CoreWebView2.DOMContentLoaded -= WebView_FileTypePolicy_DOMContentLoaded;
3541+
}
3542+
3543+
}
3544+
#endif
3545+
34213546
}
34223547
}

‎SampleApps/WebView2WpfBrowser/WebView2WpfBrowser.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
</Content>
6262
</ItemGroup>
6363
<ItemGroup>
64-
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2584-prerelease" />
64+
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2646-prerelease" />
6565
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
6666
</ItemGroup>
6767
</Project>

1 commit comments

Comments
 (1)

awrff commented on Aug 4, 2024

@awrff

Hi, I don't know if this problem only happens to me but I run this project on my visual studio in debug mode, then this exception comes up.
image
It seems that a experimental interface is no longer supported in the new prerelease of webview2 sdk?
Then I revert the code to last commit and everything works fine.

Please sign in to comment.