Skip to content

Commit d34b060

Browse files
authored
Merge pull request #1036 from MicrosoftEdge/TryUpdateRuntime-draft
Add TryUpdateRuntime API
2 parents ab3acaa + 07795c0 commit d34b060

1 file changed

Lines changed: 229 additions & 0 deletions

File tree

specs/TryUpdateRuntime.md

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Background
2+
The new version of an app might requires a newer version of Edge WebView2 Runtime. The app updater might want to ensure that the newer version of Edge WebView2 Runtime
3+
is installed before updating the app to the newer version. The app could also update to newer version with some feature disabled, and then request update so that it
4+
could move to newer version of Edge WebView2 Runtime and enable those features faster.
5+
Edge WebView2 Runtime is auto updated and normally the latest version should be already installed. However, there could be cases that we need trigger Edge WebView2 Runtime
6+
update to ensure coordinated app and runtime update.
7+
8+
# Description
9+
You may call the `TryUpdateRuntime` API to check and install updates to installed Edge WebView2 Runtime. This is useful when the app wants to coordinate app and
10+
Edge WebView2 Runtime update.
11+
12+
# Examples
13+
## .NET, WinRT
14+
```c#
15+
using Microsoft.Web.WebView2.Core;
16+
async protected bool EnsureWebView2RuntimeVersion(string minimalVersionRequired)
17+
{
18+
string currentRuntimeVersion = CoreWebView2Environment.GetAvailableBrowserVersionString();
19+
if (CoreWebView2Environment.CompareBrowserVersions(currentRuntimeVersion, minimalVersionRequired) < 0)
20+
{
21+
auto environment = await CoreWebView2Environment.CreateAsync();
22+
auto updateResult = await environment.TryUpdateRuntimeAsync();
23+
if (updateResult.UpdateRuntimeStatus != CoreWebView2RuntimeUpdateStatus.Updated)
24+
return false;
25+
}
26+
// check runtime version again
27+
currentRuntimeVersion = CoreWebView2Environment.GetAvailableBrowserVersionString();
28+
return (CoreWebView2Environment.CompareBrowserVersions(currentRuntimeVersion, minimalVersionRequired) >= 0);
29+
}
30+
31+
// For the scenario where the app wants to light up features fast while running with the old version.
32+
{
33+
...
34+
// Listen to NewBrowserVersionAvailable to take action.
35+
webView2Environment.NewBrowserVersionAvailable += delegate (object sender, object args)
36+
{
37+
// See the NewBrowserVersionAvailable documentation for more information
38+
// Close current WebView2 Control
39+
// Wait for it to completely shutdown
40+
// Recreate WebView2 Control to run with newer version
41+
};
42+
43+
// Trigger Edge WebView2 Runtime update, ignore update result and rely on NewBrowserVersionAvailable to take action.
44+
EnsureWebView2RuntimeVersion(desiredVersion);
45+
}
46+
47+
```
48+
## Win32 C++
49+
```cpp
50+
bool IsCurrentVersionSameOrNewer(std::wstring minimalVersionRequired)
51+
{
52+
wil::unique_cotaskmem_string currentVersion;
53+
HRESULT hr = GetAvailableCoreWebView2BrowserVersionString(nullptr, &currentVersion);
54+
if (FAILED(hr) || (currentVersion == nullptr))
55+
{
56+
return false;
57+
}
58+
int versionComparisonResult;
59+
CompareBrowserVersions(currentVersion.get(), minimalVersionRequired.c_str(), &versionComparisonResult);
60+
return (versionComparisonResult >= 0)
61+
}
62+
63+
void EnsureWebView2RuntimeVersion(std::function<void(bool)> const& callback, std::wstring minimalVersionRequired)
64+
{
65+
if (IsCurrentVersionSameOrNewer(minimalVersionRequired))
66+
{
67+
callback(true);
68+
return;
69+
}
70+
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
71+
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, options.Get(),
72+
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
73+
[callback, minimalVersionRequired](HRESULT result, ICoreWebView2Environment* environment) -> HRESULT {
74+
wil::com_ptr<ICoreWebView2Environment> webViewEnvironment = environment;
75+
auto experimentalEnvironment3 =
76+
webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment3>();
77+
HRESULT hr = experimentalEnvironment3->TryUpdateRuntime(
78+
Callback<ICoreWebView2ExperimentalTryUpdateRuntimeCompletedHandler>(
79+
[callback, minimalVersionRequired, experimentalEnvironment3](HRESULT errorCode,
80+
ICoreWebView2ExperimentalUpdateRuntimeResult* result) -> HRESULT {
81+
COREWEBVIEW2_RUNTIME_UPDATE_STATUS updateStatus =
82+
COREWEBVIEW2_RUNTIME_UPDATE_STATUS_FAILED;
83+
if ((errorCode == S_OK) && result)
84+
{
85+
CHECK_FAILURE(result->get_UpdateRuntimeStatus(&updateStatus));
86+
}
87+
if (updateStatus != COREWEBVIEW2_RUNTIME_UPDATE_STATUS_UPDATED)
88+
{
89+
callback(false);
90+
}
91+
else
92+
{
93+
callback(IsCurrentVersionSameOrNewer(minimalVersionRequired));
94+
}
95+
return S_OK;
96+
})
97+
.Get());
98+
return S_OK;
99+
})
100+
.Get());
101+
}
102+
103+
```
104+
105+
# Remarks
106+
See comments in [API Details](#api-details) section below.
107+
108+
# API Notes
109+
See [API Details](#api-details) section below for API reference.
110+
111+
# API Details
112+
113+
## Win32 C++
114+
```IDL
115+
/// Status of TryUpdateRuntime operation result.
116+
[v1_enum] typedef enum COREWEBVIEW2_UPDATE_RUNTIME_STATUS {
117+
118+
/// No update for Edge WebView2 Runtime is available.
119+
/// Latest version of Edge WebView2 Runtime is already installed.
120+
COREWEBVIEW2_UPDATE_RUNTIME_STATUS_NO_UPDATE,
121+
122+
/// Edge WebView2 Runtime is updated successfully.
123+
COREWEBVIEW2_UPDATE_RUNTIME_STATUS_UPDATED,
124+
125+
/// Edge WebView2 Runtime update is blocked by group policy.
126+
COREWEBVIEW2_UPDATE_RUNTIME_STATUS_BLOCKED_BY_POLICY,
127+
128+
/// Edge WebView2 Runtime update failed.
129+
/// See `UpdateError` property of UpdateRuntimeResult for more
130+
/// information about the failure.
131+
COREWEBVIEW2_UPDATE_RUNTIME_STATUS_FAILED,
132+
} COREWEBVIEW2_UPDATE_RUNTIME_STATUS;
133+
134+
135+
/// The TryUpdateRuntime operation result.
136+
[uuid(DD503E49-AB19-47C0-B2AD-6DDD09CC3E3A), object, pointer_default(unique)]
137+
interface ICoreWebView2ExperimentalUpdateRuntimeResult : IUnknown {
138+
139+
/// The status for the TryUpdateRuntime operation.
140+
[propget] HRESULT Status(
141+
[ out, retval ] COREWEBVIEW2_UPDATE_RUNTIME_STATUS * status);
142+
143+
/// The update error happened while trying to update Edge WebView2 Runtime.
144+
[propget] HRESULT UpdateError([out, retval] HRESULT* updateError);
145+
}
146+
147+
/// The caller implements this interface to receive the TryUpdateRuntime result.
148+
[uuid(F1D2D722-3721-499C-87F5-4C405260697A), object, pointer_default(unique)]
149+
interface ICoreWebView2ExperimentalTryUpdateRuntimeCompletedHandler : IUnknown {
150+
151+
/// Provides the result for the TryUpdateRuntime operation.
152+
/// `errorCode` will be S_OK if the update operation can be performed
153+
/// normally, regardless of whether we could update the Edge WebView2
154+
/// Runtime. If an unexpected error interrupts the update operation, error
155+
/// code of that unexpected error would be set as `errorCode`.
156+
/// When update operation can be performed normally, but update resulted in
157+
/// failure, like download failed, the error code would be presented as
158+
/// `UpdateError` property of ICoreWebView2ExperimentalUpdateRuntimeResult.
159+
HRESULT Invoke([in] HRESULT errorCode,
160+
[in] ICoreWebView2ExperimentalUpdateRuntimeResult * result);
161+
}
162+
163+
/// This interface is an extension of the ICoreWebView2Environment. An object
164+
/// implementing the ICoreWebView2ExperimentalEnvironment3 interface will also
165+
/// implement ICoreWebView2Environment.
166+
[uuid(9A2BE885-7F0B-4B26-B6DD-C969BAA00BF1), object, pointer_default(unique)]
167+
interface ICoreWebView2ExperimentalEnvironment3 : IUnknown {
168+
/// Try to update the installed Microsoft Edge WebView2 Runtime.
169+
/// This will potentially result in a new version of the Edge WebView2
170+
/// Runtime being installed and `NewBrowserVersionAvailable` event being raised.
171+
/// There is no guarantee on the order of that event being raised and
172+
/// TryUpdateRuntime's completed handler being invoked. Besides the
173+
/// `NewBrowserVersionAvailable` event, there will be no impact to any
174+
/// currently running WebView2s when the update is installed.
175+
/// The latest version can always be queried using the
176+
/// `GetAvailableCoreWebView2BrowserVersionString` API.
177+
/// The TryUpdateRuntime method is only supported for an installed Edge WebView2
178+
/// Runtime. When running a fixed version Edge WebView2 Runtime or non stable
179+
/// channel Edge browser, this API will return `HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)`.
180+
/// There could only be one active TryUpdateRuntime operation, calling this API
181+
/// before completed handler for previous call is invoked will fail with
182+
/// `HRESULT_FROM_WIN32(ERROR_BUSY)`.
183+
/// Calling this API repeatedly in a short period of time, will also fail with
184+
/// `HRESULT_FROM_WIN32(ERROR_BUSY)`. Don't call the API more than 3 times
185+
/// within 5 minutes.
186+
/// The TryUpdateRuntime operation is associated with the CoreWebView2Environment
187+
/// object and any ongoing TryUpdateRuntime operation will be aborted when the
188+
/// associated CoreWebView2Environment along with the CoreWebView2 objects that
189+
/// are created by the CoreWebView2Environment object are all released. In this
190+
/// case, the completed handler will be invoked with `S_OK` as `errorCode` and a
191+
/// result object with `Status` of COREWEBVIEW2_UPDATE_RUNTIME_STATUS_FAILED and
192+
/// `UpdateError` as `E_ABORT`.
193+
///
194+
/// \snippet AppWindow.cpp UpdateRuntime
195+
HRESULT TryUpdateRuntime(
196+
[in] ICoreWebView2ExperimentalTryUpdateRuntimeCompletedHandler *
197+
handler);
198+
}
199+
```
200+
## .NET WinRT
201+
```c#
202+
namespace Microsoft.Web.WebView2.Core
203+
{
204+
public enum CoreWebView2UpdateRuntimeStatus
205+
{
206+
NoUpdate = 0,
207+
Updated = 1,
208+
BlockedByPolicy = 2,
209+
Failed = 3,
210+
}
211+
212+
public partial class CoreWebView2UpdateRuntimeResult
213+
{
214+
public CoreWebView2UpdateRuntimeStatus Status
215+
{
216+
get;
217+
}
218+
public int UpdateError
219+
{
220+
get;
221+
}
222+
}
223+
224+
public partial class CoreWebView2Environment
225+
{
226+
public async Task<CoreWebView2UpdateRuntimeResult> TryUpdateRuntimeAsync()
227+
}
228+
}
229+
```

0 commit comments

Comments
 (0)