Skip to content

Commit bd570e5

Browse files
Diana QuDiana Qudavid-risney
authored
API Review: Process Id (#1763)
* [Process Info API] Draft Review (#1663) * draft child process id spe * remove white space * add count * modify c# section * correct typo * add sample code c+ * add comment to c# * change wording of example * rename and use updated template * update sample * modify c++ sample * add c# sample * update with moving to environment * add background section * update interface * update API details section * d * modify enum and related change * change API naming * add custom type for .net * update with ICoreWebView2StagingProcessInfo * minor chang * fix lower case issue * change comment * update .NET sample code * remove staging prefix * update .NET sample code * update win32 sample code * rename * update sample code * change naming Co-authored-by: Diana Qu <xiaqu@microsoft.com> * update c# API details * skip *collection * Update specs/ProcessInfo.md Co-authored-by: David Risney <dave@deletethis.net> * change from core to environment * api review comment: sample snipet side and doc style * COM code naming change * renaming 's on c# * remove unknow incase new type being added in the future * collection non pural * getProcessInfos change * c#: get_processInfos -> GetProcessInfos() Co-authored-by: Diana Qu <xiaqu@microsoft.com> Co-authored-by: David Risney <dave@deletethis.net>
1 parent a508f39 commit bd570e5

1 file changed

Lines changed: 263 additions & 0 deletions

File tree

specs/ProcessInfo.md

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
Process Info
2+
===
3+
4+
# Background
5+
Provide end developer a new API to get all browser and child process ID with its type. End developers can use this API to track performance more closely, instead of using the task manager API to gather this information which requires a lot of preset. The process list provides all processes under the same user data folder, processes from multiple WebView creations will also be collected.
6+
Note: Crashpad process is not captured.
7+
8+
# Examples
9+
## WinRT and .NET
10+
```c#
11+
IReadOnlyList<CoreWebView2ProcessInfo> _processList = new List<CoreWebView2ProcessInfo>();
12+
13+
void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
14+
{
15+
if (e.IsSuccess)
16+
{
17+
// ...
18+
webView.CoreWebView2.Environment.ProcessInfosChanged += WebView_ProcessInfosChanged;
19+
}
20+
}
21+
22+
void WebView_ProcessInfosChanged(object sender, object e)
23+
{
24+
_processList = webView.CoreWebView2.Environment.GetProcessInfos();
25+
}
26+
27+
void PerfInfoCmdExecuted(object target, ExecutedRoutedEventArgs e)
28+
{
29+
string result;
30+
int processListCount = _processList.Count;
31+
if (processListCount == 0)
32+
{
33+
result = "No process found.";
34+
}
35+
else
36+
{
37+
result = $"{processListCount} child process(s) found\n\n";
38+
for (int i = 0; i < processListCount; ++i)
39+
{
40+
uint processId = _processList[i].ProcessId;
41+
CoreWebView2ProcessKind kind = _processList[i].Kind;
42+
43+
var proc = Process.GetProcessById((int)processId);
44+
var memoryInBytes = proc.PrivateMemorySize64;
45+
var b2kb = memoryInBytes / 1024;
46+
result = result + $"Process ID: {processId} | Process Kind: {kind} | Memory: {b2kb} KB\n";
47+
}
48+
}
49+
50+
MessageBox.Show(this, result, "Process List");
51+
}
52+
```
53+
## Win32 C++
54+
```cpp
55+
ProcessComponent::ProcessComponent(AppWindow* appWindow)
56+
: m_appWindow(appWindow), m_webView(appWindow->GetWebView())
57+
{
58+
// Register a handler for the ProcessInfosChanged event.
59+
//! [ProcessInfosChanged]
60+
wil::com_ptr<ICoreWebView2Environment> environment = appWindow->GetWebViewEnvironment();
61+
CHECK_FAILURE(environment->GetProcessInfos(&m_processCollection));
62+
CHECK_FAILURE(environment->add_ProcessInfosChanged(
63+
Callback<ICoreWebView2ProcessInfosChangedEventHandler>(
64+
[this](ICoreWebView2Environment* sender, IUnknown* args) -> HRESULT {
65+
CHECK_FAILURE(sender->GetProcessInfos(&m_processCollection));
66+
67+
return S_OK;
68+
})
69+
.Get(),
70+
&m_processInfosChangedToken));
71+
//! [ProcessInfosChanged]
72+
}
73+
74+
std::wstring ProcessComponent::ProcessKindToString(const COREWEBVIEW2_PROCESS_KIND kind)
75+
{
76+
switch (kind)
77+
{
78+
#define KIND_ENTRY(kindValue) \
79+
case kindValue: \
80+
return L#kindValue;
81+
82+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_BROWSER);
83+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_RENDERER);
84+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_UTILITY);
85+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_SANDBOX_HELPER);
86+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_GPU);
87+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_PPAPI_PLUGIN);
88+
KIND_ENTRY(COREWEBVIEW2_PROCESS_KIND_PPAPI_BROKER);
89+
90+
#undef KIND_ENTRY
91+
}
92+
93+
return L"PROCESS KIND: " + std::to_wstring(static_cast<uint32_t>(kind));
94+
}
95+
96+
// Get the process info
97+
//! [ProcessInfosChanged]
98+
void ProcessComponent::PerformanceInfo()
99+
{
100+
std::wstring result;
101+
UINT processListCount;
102+
CHECK_FAILURE(m_processCollection->get_Count(&processListCount));
103+
104+
if (processListCount == 0)
105+
{
106+
result += L"No process found.";
107+
}
108+
else
109+
{
110+
result += std::to_wstring(processListCount) + L" process(s) found";
111+
result += L"\n\n";
112+
for (UINT i = 0; i < processListCount; ++i)
113+
{
114+
wil::com_ptr<ICoreWebView2StagingProcessInfo> processInfo;
115+
CHECK_FAILURE(m_processCollection->GetValueAtIndex(i, &processInfo));
116+
117+
INT32 processId = 0;
118+
COREWEBVIEW2_PROCESS_KIND kind;
119+
CHECK_FAILURE(processInfo->get_ProcessId(&processId));
120+
CHECK_FAILURE(processInfo->get_Kind(&kind));
121+
122+
WCHAR id[4096] = L"";
123+
StringCchPrintf(id, ARRAYSIZE(id), L"Process ID: %u", processId);
124+
125+
HANDLE processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
126+
PROCESS_MEMORY_COUNTERS_EX pmc;
127+
GetProcessMemoryInfo(
128+
processHandle, reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmc), sizeof(pmc));
129+
SIZE_T virtualMemUsed = pmc.PrivateUsage / 1024;
130+
WCHAR memory[4096] = L"";
131+
StringCchPrintf(memory, ARRAYSIZE(memory), L"Memory: %u", virtualMemUsed);
132+
CloseHandle(processHandle);
133+
134+
result = result + id + L" | Process Kind: " + ProcessKindToString(kind) + L" | " +
135+
memory + L" KB\n";
136+
}
137+
}
138+
MessageBox(nullptr, result.c_str(), L"Memory Usage", MB_OK);
139+
}
140+
//! [ProcessInfoChanged]
141+
```
142+
143+
# API Details
144+
```
145+
interface ICoreWebView2Environment6;
146+
interface ICoreWebView2ProcessInfo;
147+
interface ICoreWebView2ProcessInfoCollection;
148+
interface ICoreWebView2ProcessInfosChangedEventHandler;
149+
150+
[v1_enum]
151+
typedef enum COREWEBVIEW2_PROCESS_KIND {
152+
/// Indicates the browser process kind.
153+
COREWEBVIEW2_PROCESS_KIND_BROWSER,
154+
155+
/// Indicates the render process kind.
156+
COREWEBVIEW2_PROCESS_KIND_RENDERER,
157+
158+
/// Indicates the utility process kind.
159+
COREWEBVIEW2_PROCESS_KIND_UTILITY,
160+
161+
/// Indicates the sandbox helper process kind.
162+
COREWEBVIEW2_PROCESS_KIND_SANDBOX_HELPER,
163+
164+
/// Indicates the GPU process kind.
165+
COREWEBVIEW2_PROCESS_KIND_GPU,
166+
167+
/// Indicates the PPAPI plugin process kind.
168+
COREWEBVIEW2_PROCESS_KIND_PPAPI_PLUGIN,
169+
170+
/// Indicates the PPAPI plugin broker process kind.
171+
COREWEBVIEW2_PROCESS_KIND_PPAPI_BROKER,
172+
} COREWEBVIEW2_PROCESS_KIND;
173+
174+
[uuid(20856F87-256B-41BE-BD64-AB1C36E3D944), object, pointer_default(unique)]
175+
interface ICoreWebView2Environment6 : ICoreWebView2Environment5
176+
{
177+
/// Adds an event handler for the `ProcessInfosChanged` event.
178+
///
179+
/// \snippet ProcessComponent.cpp ProcessInfosChanged
180+
HRESULT add_ProcessInfosChanged(
181+
[in] ICoreWebView2ProcessInfosChangedEventHandler* eventHandler,
182+
[out] EventRegistrationToken* token);
183+
184+
/// Remove an event handler previously added with `add_ProcessInfosChanged`.
185+
HRESULT remove_ProcessInfosChanged(
186+
[in] EventRegistrationToken token);
187+
188+
/// Returns the `ICoreWebView2ProcessInfoCollection`
189+
/// Provide a list of all process using same user data folder.
190+
HRESULT GetProcessInfos([out, retval]ICoreWebView2ProcessInfoCollection** value);
191+
}
192+
193+
/// Provides a set of properties for a process in the `ICoreWebView2Environment`.
194+
[uuid(7798D399-52A1-4823-AD6A-1F3EDD74B0B6), object, pointer_default(unique)]
195+
interface ICoreWebView2ProcessInfo : IUnknown {
196+
197+
/// The process id of the process.
198+
[propget] HRESULT ProcessId([out, retval] INT32* value);
199+
200+
/// The kind of the process.
201+
[propget] HRESULT Kind([out, retval] COREWEBVIEW2_PROCESS_KIND* kind);
202+
}
203+
204+
/// A list containing process id and corresponding process type.
205+
[uuid(5356F3B3-4859-4763-9C95-837CDEEE8912), object, pointer_default(unique)]
206+
interface ICoreWebView2ProcessInfoCollection : IUnknown {
207+
/// The number of process contained in the ICoreWebView2ProcessInfoCollection.
208+
[propget] HRESULT Count([out, retval] UINT* count);
209+
210+
/// Gets the `ICoreWebView2ProcessInfo` located in the `ICoreWebView2ProcessInfoCollection`
211+
/// at the given index.
212+
HRESULT GetValueAtIndex([in] UINT32 index,
213+
[out, retval] ICoreWebView2ProcessInfo** processInfo);
214+
}
215+
216+
/// An event handler for the `ProcessInfosChanged` event.
217+
[uuid(CFF13C72-2E3B-4812-96FB-DFDDE67FBE90), object, pointer_default(unique)]
218+
interface ICoreWebView2ProcessInfosChangedEventHandler : IUnknown {
219+
/// Provides the event args for the corresponding event. No event args exist
220+
/// and the `args` parameter is set to `null`.
221+
HRESULT Invoke([in] ICoreWebView2* sender, [in] IUnknown* args);
222+
}
223+
```
224+
225+
```c# (but really MIDL3)
226+
namespace Microsoft.Web.WebView2.Core
227+
{
228+
// ...
229+
runtimeclass CoreWebView2ProcessInfo;
230+
231+
/// Kind of process type used in the CoreWebView2ProcessInfoCollection.
232+
enum CoreWebView2ProcessKind
233+
{
234+
Browser = 0,
235+
Renderer = 1,
236+
Utility = 2,
237+
SandboxHelper = 3,
238+
Gpu = 4,
239+
PpapiPlugin = 5,
240+
PpapiBroker = 6,
241+
};
242+
243+
runtimeclass CoreWebView2ProcessInfo
244+
{
245+
// ICoreWebView2ProcessInfo members
246+
Int32 ProcessId { get; };
247+
248+
CoreWebView2ProcessKind Kind { get; };
249+
}
250+
251+
runtimeclass CoreWebView2Environment
252+
{
253+
/// Gets a list of process.
254+
IVectorView<CoreWebView2ProcessInfo> GetProcessInfos();
255+
event Windows.Foundation.TypedEventHandler<CoreWebView2Environment, Object> ProcessInfosChanged;
256+
257+
// ...
258+
}
259+
260+
// ...
261+
}
262+
```
263+

0 commit comments

Comments
 (0)