Skip to content
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
50 changes: 40 additions & 10 deletions wv2util/HostAppList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public HostAppEntry(
string runtimePath, // Path to the WebView2 client DLL
string userDataPath, // Path to the user data folder
string[] interestingLoadedDllPaths, // a list of full paths of DLLs that are related to WebView2 in some way
int browserProcessPid) // PID of the browser process
int browserProcessPid,
IntPtr[] hwnds) // PID of the browser process
{
Kind = kind;
ExecutablePath = exePath == null ? "Unknown" : exePath;
Expand All @@ -61,6 +62,7 @@ public HostAppEntry(
UserDataPath = userDataPath == null ? "Unknown" : userDataPath;
InterestingLoadedDllPaths = interestingLoadedDllPaths;
BrowserProcessPID = browserProcessPid;
Hwnds = hwnds == null ? new IntPtr[0] : hwnds;
}

public string DisplayLabel
Expand Down Expand Up @@ -98,6 +100,7 @@ public string DisplayLabel
public string UserDataPath { get; private set; }
public string[] InterestingLoadedDllPaths { get; private set; }
public int BrowserProcessPID { get; private set; } = 0;
public IntPtr[] Hwnds { get; private set; }
public string IntegrityLevel
{
get
Expand Down Expand Up @@ -401,7 +404,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
msedgewebview2Process.MainModule.FileName,
userDataPathAndProcessType.Item1,
null,
0);
0,
null);
}

if (parentProcess != null)
Expand All @@ -426,7 +430,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
hostAppEntry.Runtime.ExePath,
userDataFolder,
hostAppEntry.InterestingLoadedDllPaths,
msedgewebview2Process.Id);
msedgewebview2Process.Id,
hostAppEntry.Hwnds);
newHostAppEntry.Children.AddRange(hostAppEntry.Children);
newHostAppEntry.Children.Add(currentProcessEntry);

Expand Down Expand Up @@ -470,7 +475,8 @@ private static IEnumerable<HostAppEntry> GetHostAppEntriesFromMachineByProcessMo
ClientDllPathToRuntimePath(interestingDllPaths.Item1),
null,
interestingDllPaths.Item3,
0));
0,
null));
}
}
return results;
Expand Down Expand Up @@ -531,7 +537,8 @@ public static IEnumerable<HostAppEntry> GetHostAppEntriesFromMachineByPipeEnumer
ClientDllPathToRuntimePath(clientDllPath),
null,
interestingDllPaths,
0));
0,
null));
}
}
};
Expand Down Expand Up @@ -566,6 +573,7 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
if (hostAppEntry.BrowserProcessPID == 0)
{
HashSet<int> runtimePids = new HashSet<int>();
Dictionary<int, HashSet<IntPtr>> runtimePidToHwndMap = new Dictionary<int, HashSet<IntPtr>>();

// And find corresponding top level windows for just this PID.
if (pidToTopLevelHwndsMap.TryGetValue(hostAppEntry.PID, out var topLevelHwnds))
Expand All @@ -584,9 +592,17 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
{
childHwnd = PInvoke.User32.GetProp(hostAppLeafHwnd, "CrossProcessChildHWND");
}

if (childHwnd != IntPtr.Zero)
{
runtimePids.Add(HwndUtil.GetWindowProcessId(childHwnd));
int runtimePid = HwndUtil.GetWindowProcessId(childHwnd);
runtimePids.Add(runtimePid);

if (!runtimePidToHwndMap.TryGetValue(runtimePid, out HashSet<IntPtr> runtimeHwnds))
{
runtimePidToHwndMap[runtimePid] = runtimeHwnds = new HashSet<IntPtr>();
}
runtimeHwnds.Add(childHwnd);
}
}
}
Expand All @@ -602,6 +618,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
var userDataPathAndProcessType = GetUserDataPathAndProcessTypeFromProcessViaCommandLine(runtimeProcess);
userDataFolder = userDataPathAndProcessType.Item1;

runtimePidToHwndMap.TryGetValue(runtimePid, out HashSet<IntPtr> runtimeHwnds);

var runtimeEntry = new HostAppEntry(
"host",
hostAppEntry.ExecutablePath,
Expand All @@ -611,7 +629,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
hostAppEntry.Runtime.ExePath,
userDataFolder,
hostAppEntry.InterestingLoadedDllPaths,
runtimePid);
runtimePid,
runtimeHwnds?.ToArray());
runtimeEntry.Children.AddRange(hostAppEntry.Children);
runtimeEntry.Children.Add(new HostAppEntry(
userDataPathAndProcessType.Item2,
Expand All @@ -622,7 +641,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
runtimeProcess.MainModule.FileName,
userDataFolder,
null,
0));
0,
runtimeEntry.Hwnds));
hostAppEntriesWithRuntimePID.Add(runtimeEntry);
added = true;
}
Expand Down Expand Up @@ -653,6 +673,7 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
List<HostAppEntry> hostAppEntriesResults = new List<HostAppEntry>();
Dictionary<int, HashSet<int>> parentPidToChildPidsMap = new Dictionary<int, HashSet<int>>();
var topLevelHwnds = HwndUtil.GetTopLevelHwnds(null, true);
Dictionary<int, HashSet<IntPtr>> childPidToHwnd = new Dictionary<int, HashSet<IntPtr>>();

// Then find all child (and child of child of...) windows that have appropriate class name
foreach (var topLevelHwnd in topLevelHwnds)
Expand Down Expand Up @@ -681,6 +702,12 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
}
childPids.Add(childPid);
}

if (!childPidToHwnd.TryGetValue(childPid, out HashSet<IntPtr> childHwnds))
{
childPidToHwnd[childPid] = childHwnds = new HashSet<IntPtr>();
}
childHwnds.Add(childHwnd);
}
}
}
Expand All @@ -702,6 +729,7 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
{
var userDataPathAndProcessType = GetUserDataPathAndProcessTypeFromProcessViaCommandLine(runtimeProcess);
string userDataFolder = userDataPathAndProcessType.Item1;
childPidToHwnd.TryGetValue(childPid, out HashSet<IntPtr> runtimeHwnds);

var runtimeEntry = new HostAppEntry(
"host",
Expand All @@ -712,7 +740,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
hostAppEntry.Runtime.ExePath,
userDataFolder,
hostAppEntry.InterestingLoadedDllPaths,
childPid);
childPid,
runtimeHwnds?.ToArray());
runtimeEntry.Children.Add(new HostAppEntry(
userDataPathAndProcessType.Item2,
runtimeProcess.MainModule.FileName,
Expand All @@ -722,7 +751,8 @@ private static IEnumerable<HostAppEntry> AddRuntimeProcessInfoToHostAppEntriesBy
runtimeProcess.MainModule.FileName,
userDataFolder,
null,
0));
0,
runtimeEntry.Hwnds));
runtimeEntry.Children.AddRange(hostAppEntry.Children);
hostAppEntriesResults.Add(runtimeEntry);
added = true;
Expand Down
18 changes: 18 additions & 0 deletions wv2util/HwndUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,5 +175,23 @@ public static string GetClassName(IntPtr hwnd)
}
return className;
}

public static System.Windows.Rect ToSystemWindowsRect(this PInvoke.RECT rectAsPInvokeRect)
{
System.Windows.Rect rectAsSystemWindowsRect = new System.Windows.Rect();
rectAsSystemWindowsRect.X = rectAsPInvokeRect.left;
rectAsSystemWindowsRect.Y = rectAsPInvokeRect.top;
rectAsSystemWindowsRect.Width = rectAsPInvokeRect.right - rectAsPInvokeRect.left;
rectAsSystemWindowsRect.Height = rectAsPInvokeRect.bottom - rectAsPInvokeRect.top;
return rectAsSystemWindowsRect;
}
public static System.Windows.Rect GetWindowRect(IntPtr hwnd)
{
if (!PInvoke.User32.GetWindowRect(hwnd, out var rect))
{
throw new PInvoke.Win32Exception(PInvoke.Kernel32.GetLastError());
}
return rect.ToSystemWindowsRect();
}
}
}
3 changes: 2 additions & 1 deletion wv2util/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" Margin="5 5 5 5" Content="Discover more Host Apps information (slower)" IsChecked="{Binding Source={StaticResource HostAppList}, Path=ShouldDiscoverSlowly, Mode=TwoWay}" x:Name="HostAppsDiscoverSlowlyCheckbox" Checked="HostAppsDiscoverSlowlyCheckbox_Checked" Unchecked="HostAppsDiscoverSlowlyCheckbox_Checked"/>
<TreeView Grid.Row="1" Grid.Column="0" Grid.RowSpan="20" Margin="5 5 5 5" x:Name="HostAppTreeView" ItemsSource="{Binding .}" SelectedValuePath="Model">
<CheckBox Grid.Row="0" Grid.Column="1" Margin="5 5 5 5" Content="Highlight WebView2 (experimental)" IsChecked="False" x:Name="HostAppsVisuallyHighlightWebView2sCheckbox" Checked="HostAppsVisuallyHighlightWebView2sCheckbox_Checked" Unchecked="HostAppsVisuallyHighlightWebView2sCheckbox_Checked"/>
<TreeView Grid.Row="1" Grid.Column="0" Grid.RowSpan="20" Margin="5 5 5 5" x:Name="HostAppTreeView" ItemsSource="{Binding .}" SelectedValuePath="Model" SelectedItemChanged="HostAppTreeViewSelectionChanged">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
Expand Down
34 changes: 34 additions & 0 deletions wv2util/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,40 @@ private void RuntimeListViewSelectionChanged(object sender, SelectionChangedEven
}
}
}
private List<OverlayWindow> m_openOverlayWindows = new List<OverlayWindow>();
private void UpdateOverlayWindows()
{
foreach (var overlayWindow in m_openOverlayWindows)
{
overlayWindow.CloseOverlay();
}
m_openOverlayWindows.Clear();

if (this.HostAppsVisuallyHighlightWebView2sCheckbox.IsChecked.GetValueOrDefault(true))
{

HostAppEntry selection = HostAppTreeViewSelectedItem;
if (selection != null)
{
foreach (var hwnd in selection?.Hwnds)
{
m_openOverlayWindows.Add(
OverlayWindow.OpenOverlayForHwnd(hwnd));
}
}

}
}
private void HostAppTreeViewSelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
UpdateOverlayWindows();
}

private void HostAppsVisuallyHighlightWebView2sCheckbox_Checked(object sender, RoutedEventArgs e)
{
UpdateOverlayWindows();
}

private void AppOverrideRuntimePathButton_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog
Expand Down Expand Up @@ -427,5 +460,6 @@ private void NewsBlock_Click(object sender, MouseButtonEventArgs e)
: Visibility.Visible;
}
}

}
}
9 changes: 9 additions & 0 deletions wv2util/OverlayWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Window x:Class="wv2util.OverlayWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:wv2util"
mc:Ignorable="d"
Title="Overlay" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Opacity="0.25" ResizeMode="NoResize" ShowInTaskbar="False" Topmost="False" Focusable="False" IsHitTestVisible="False" IsTabStop="False" Background="#FF84B9FF" MouseUp="Window_MouseUp">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The blue color is maybe too nice looking and can be hard to tell its actually not part of the web content. How about changing the color to orange and is it practical to add a darker orange border around the edge?

</Window>
Loading