GithubHelp home page GithubHelp logo

snoopwpf / snoopwpf Goto Github PK

View Code? Open in Web Editor NEW
2.1K 88.0 346.0 30.19 MB

Snoop - The WPF Spy Utility

License: Microsoft Public License

C++ 1.82% C# 96.61% PowerShell 0.70% C 0.55% Shell 0.30% Batchfile 0.02%
wpf spy utility hacktoberfest snoop wpf-spy-utility xaml

snoopwpf's Introduction

Snoop

Snoop is an open source WPF spying utility originally created by Pete Blois and is currently maintained by Bastian Schmidt.

It allows you to spy/browse the visual, logical and automation tree of any running WPF application (without the need for a debugger).
You can change property values, view triggers, set breakpoints on property changes and many more things.

Build status for master branch Build status for develop branch Chocolatey version Chocolatey download count

Contact

  • Join the chat at https://gitter.im/snoopwpf/Lobby
  • Twitter

Where can i download Snoop?/How can i install Snoop?

  • Chocolatey for stable and some preview versions
  • GitHub releases for stable versions
  • AppVeyor for the latest preview versions (built on every code change)
  • You need at least .NET Framework 4.6.2 to run Snoop

Supported .NET versions

  • .NET Framework >= 4.6.2
  • .NET >= 6
    • Tested with 6, 7 and 8. Future versions might just work.
    • Restrictions: Self-Contained single file applications are not supported as there is no reliable way to get a handle to the .NET runtime

Versions

You can read the changelog for details on what changed in which version.

Breaking:

  • Dropped support for all .NET Framework versions prior to .NET 4.6.2
  • Dropped support for .NET 3.1 and NET 5

Highlights:

  • Improved settings system that does not rely on System.Configuration
    The new system allows sharing of settings between different snooped applications.
    It also allows to define settings for whole directory trees.
  • It's now possible to hide properties from Snoop in it's default view.
    Just annotate your properties with [System.ComponentModel.BrowsableAttribute(false)].
  • Added the ability to show browser dev tools on browser controls.
    WebView2 and CefSharp are currently supported.
  • Added dark theme

Breaking:

  • Dropped support for all .NET Framework versions prior to .NET 4.5.2
  • Dropped support for .NET 3.0
  • Added support for .NET versions >= 6.0 (by not explicitly blocking versions greater than 6.0)

Highlights:

  • Support for .NET 6.0
  • Support for ARM/ARM64
  • New "Diagnostics" view
  • Settings for highlighting
  • Artifacts are digitally signed thanks to SignPath.io (MSI, Chocolatey NUPKG and zip)

Breaking:

  • Dropped support for all .NET versions prior to .NET 4.5.1

Highlights:

  • Support for .NET Core (3.0, 3.1 and 5.0) (including self contained and single file applications)
  • Rewritten injector code
  • You no longer have to have installed any Microsoft Visual C++ Redistributable(s)
  • Snooping disabled controls when holding CTRL + SHIFT works now
  • Snoop now filters uncommon properties by default
  • Snoop is now able to show MergedDictionaries from ResourceDictionary
  • Snoop now has two tracking modes.
    • Holding CTRL tries to skip template parts => this is changed to CTRL + ALT in newer versions
    • Holding CTRL + SHIFT does not skip template parts
  • Drastically improved performance of AppChooser.Refresh() (thanks @mikel785)
  • Usability improvements for process dropdown (thanks @mikel785)
  • Support for displaying the logical tree and the tree of WPF automation peers
  • Ability to inspect Popup without opening it
  • Snoop.exe and the injector launcher now support commandline args
  • Global hotkey support (just start snoop, focus a WPF application and hit CTRL + WIN + ALT + F12)

Known issues:

  • Trying to snoop a trimmed single file application might not work as trimming might have removed things Snoop relies on

Highlights:

  • Support for multiple app domains
  • Auto elevation to enable spying of elevated processes without running Snoop as administrator
  • Persistent settings for various settings
  • Improved error dialog and issue reporting
  • Rewritten window finder

Was released on September 19th, 2018. In this version we finally got rid of support for snooping WPF 3.5 applications. This allowed us to move the Snoop projects forward to Visual Studio 2017 which should make it much easier to work with Snoop's source code.

Was released on July 27th, 2018. The big addition in this version was the inclusion of the triggers tab which was a useful feature of another WPF spying utility called WPF Inspector (written by Christan Moser). It was ported to Snoop by Bastian Schmidt.

Documentation on how to use Snoop

Unfortunately there isn't any exhaustive documentation on how to use Snoop and there are plenty of hidden features. If someone is willing to work on this, please let me know. On the bright side, it is a pretty easy utility to use and learn. I have made three videos which should get most people quick started.

Here are the links to the current Snoop Tips & Tricks:

Why can't I snoop my application?

Well, you can! You will just need to use an earlier version of Snoop, in order to do so.
The minimum versions are:

Snoop .NET Framework .NET
3.0 4.0 3.0
4.0 4.5.1 3.0
5.0 4.5.2 3.1
6.0 4.6.2 6.0

How do i build Snoop?

Just open Snoop.sln with Visual Studio and build it.

Requirements:

  • Visual Studio 2022
    • C++ payloads (x86/x64 and optionally ARM/ARM64)
    • You can import the .vsconfig file in the Visual Studio installer to let it install all required components
  • .NET SDK 8.0.100 or later

Contributors

Over time contributions have been added by several people, most notably:

Code Signing

Snoop uses free code signing provided by SignPath.io and a free code signing certificate by the SignPath Foundation

snoopwpf's People

Contributors

alexprince avatar algorithman avatar ali50m avatar batzen avatar bbutner avatar bling avatar codekaizen avatar cplotts avatar dependabot-preview[bot] avatar dependabot[bot] avatar dezsiszabi avatar fornever avatar gix avatar jmbeach avatar jongleur1983 avatar kirillosenkov avatar maciekrakowski avatar magicshoebox avatar miloush avatar paulspiteri avatar simoncropp avatar stutton avatar x39 avatar zo0o0ot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

snoopwpf's Issues

Message: Cannot set Expression. It is marked as 'NonShareable' and has already been used.

When selecting Delve Binding Expression on a Binding. No errors on the binding or anything. The binding wasn't doing what I wanted, so I was trying to figure out what was going on. I really don't know how to use this feature anyway.

Stacktrace:
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Snoop.PropertyInspector.set_Target(Object value)
at Snoop.PropertyInspector.PushTarget(Object target)
at Snoop.PropertyInspector.HandleDelveBindingExpression(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.CommandManager.TransferEvent(IInputElement newSource, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Keystrokes go to Visual Studio main window when inspecting Visual Studio

Could someone please confirm if they're seeing the same behavior:

  1. Open a new instance of Visual Studio
  2. Open Snoop, inspect the instance of Visual Studio from step 1
  3. Ctrl+Shift and move mouse over some VS element, such as a toolbar button
  4. Go to Snoop, select Powershell, type $selected and press ENTER

Expected:
ENTER should commit the command into Powershell.

Actual:
ENTER goes to Visual Studio main window, and if the editor in VS is open, it sends enter there.

If this is indeed a bug that others are seeing, then I have a pull request ready that fixes this:
#44

Virus / Trojan?

The Setup.exe binary appears to be infected with some kind of virus.

snoopwpf-2.8.0\SnoopInstaller\bin\Release\Setup.exe

When run, it attempts to go out to 192.195.77.40 and download additional files.

Looking at the WiX installer source, I don't think it should be doing this.

When click the properties datagrid,throw the exception.

Message: Object reference not set to an instance of an object.
Stacktrace:
at Snoop.PropertyGrid2.HandleSort(Object sender, ExecutedRoutedEventArgs args)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Controls.GridViewColumnHeader.OnClick()
at System.Windows.Controls.GridViewColumnHeader.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Fatal ExecutionEngineException when process has hidden windows without composition target

Commit 2a5da54 changed the navigation tree to include all windows of the process. This may include windows that have been created but not yet shown. Such windows do not have a composition target yet and cannot be layouted. But using them as source of a VisualBrush will forcibly layout them and trigger WPF-internal asserts that crash the process (the managed debugger displays a fatal exception indicating process corruption which is not the case here).

Simple repro: Create a new empty WPF project and add this to the MainWindow:

public partial class MainWindow
{
    private Window window = new Window {
        Visibility = Visibility.Hidden // Must be hidden (not collapsed) to not skip layouting.
    };

    public MainWindow()
    {
        InitializeComponent();
    }
}

Missing possibility of copying value of the specific node

Let's say I want to check what is the value of the specific style. I see it's e.g. "Style.Menu.Header [Style]". Then I want to copy this value in order to find it in my project. Whenever I click on the value cell it prints out "System.Windows.Style" and this is what I can copy to clipboard - which is useless in my opinion.

Export tree

(Continuing discussion from https://snoopwpf.codeplex.com/discussions/441911)

Has there been any progress on this issue? I would be very happy if I could export the tree to anything, including plain old XML.

(My goal is to get the exact displayed text strings and their bounding boxes within the window; I don't mind calculating the bboxes from ancestor data.)

Info missing on exact requirements to open and build the tree

Should be in README.md. In particular about WIX - what exactly (is "WiX Toolset build tools" enough or do you need "WiX Toolset Visual Studio Extension" as well) , URL-s for pages where to find it/them (http://wixtoolset.org/releases/v3.11/stable, but that's still not the final path).

Also for importing targets as dependencies it would be good to add conditions like Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets')" which should prevent throwing error so that the project could load, never mind that it won't be buildable. The guy opening it will see files etc.

If it's available as a nuget package that would be an option worth considering since VS knows how to auto load packages that are dependencies, if asked nicely :-) (meaning without one nasty tag to throw error on purpose).

Oh and a warning to people not to succumb to the VS pressure to "migrate to the latest version" project which are clearly clearly marked as being CLR version specific (-3.5 and -4.0 for launcher and injector). Don't know if there's a tag to prevent that as well - VS is very much version-gready and persuasive :-)

Hang on PriorityBinding

With the attached WPF application (VS2013), Snoop hangs when viewing the properties of the TextBock.

This seems to be caused by the PriorityBinding; with a normal binding the hang does not occur.

WpfApplication6.zip

ILSpy Exception

I was exploring ILSpy version 2.2.0.1706
While expanding FoldingMargin, I observed this exception.

Exception:

Message: Object reference not set to an instance of an object.
Stacktrace:
at ICSharpCode.AvalonEdit.Folding.FoldingMarginMarker.OnRender(DrawingContext drawingContext)
at System.Windows.UIElement.Arrange(Rect finalRect)
at System.Windows.Media.VisualBrush.LayoutCallback(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Snoop 2.9 crashes on startup

Ey, Snoop stays the most awesome WPF inspection tool. It's not working for me atm, and I missed it the entire day ;)

However, it suddenly stopped working :(

Problem

When I start Snoop, it doesn't show up. After a bit of digging, I found out that so-called AppCrash reports are being created (here: C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_snoop.exe_37e7083a3a2cc8e51f6b2f47580bbdb1cf5277_00000000_3cb3fea2), and in the Event Log I also found entries about the crashes (see below).

Own steps to fix things

I wasn't sure if my install was faulty, or maybe something wrong with my installed version, so I uninstalled the one that was installed, and re-installed the latest version, and it still didn't show up.

Environment

I'm running Windows 10, upgraded to the latest edition. Visual Studio 2017 (latest one 15.8.*), full .NET Framework at least 4.6.2.

Windows Event Entry

Fault bucket 1364462021916346858, type 5
Event Name: CLR20r3
Response: Not available
Cab Id: 0

Problem signature:
P1: snoop.exe
P2: 2.9.0.0
P3: 5b5b9b0b
P4: PresentationCore
P5: 3.0.0.0
P6: 5a7d2bb4
P7: 21db
P8: a
P9: System.NullReferenceException
P10: 

Attached files:
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERF281.tmp.WERInternalMetadata.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERF31E.tmp.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERF32F.tmp.csv
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERF35F.tmp.txt

These files may be available here:
C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_snoop.exe_a0bc4fb2736589139e7b5322443942330c8a_00000000_68c6f919

Analysis symbol: 
Rechecking for solution: 0
Report Id: 536d7e93-f7ea-4185-87da-2a9f2ea2164c
Report Status: 268435456
Hashed bucket: 5675642891bd535aa2ef8afacdd5c9ea
Cab Guid: 0

Unhandled exception

Message: Specified element is already the logical child of another element. Disconnect it first.
Stacktrace:
at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
at MS.Internal.FrameworkObject.ChangeLogicalParent(DependencyObject newParent)
at System.Windows.FrameworkElement.AddLogicalChild(Object child)
at System.Windows.Controls.ContentControl.OnContentChanged(Object oldContent, Object newContent)
at System.Windows.Controls.ContentControl.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Data.BindingOperations.SetBinding(DependencyObject target, DependencyProperty dp, BindingBase binding)
at System.Windows.Controls.PopupControlService.RaiseToolTipOpeningEvent()
at System.Windows.Controls.PopupControlService.OnRaiseToolTipOpeningEvent(Object sender, EventArgs e)
at System.Windows.Threading.DispatcherTimer.FireTick(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

Is this project still being maintained?

Hi there,

i'd like to ask if this project is still being maintained.
If not, what would you suggest i should do if i'd wanted to contribute to it?

And great work on snoop. I love it!

Problems with the 2.9.0 release

Hello, and thank you for releasing a new version of Snoop, it's such a great utility.

However, the newest 2.9.0 installer does not seem to work properly.

The setup.exe simply fails with the following dialog from Windows Installer:
This installation package could not be opened. Verify that the package exists and that you can access it or contact the application vendor to verify that this is a valid Windows Installer package.
Snoop 2.8.0 was installed, but the same error message was displayed after un-installing 2.8.0.

The snoop.msi installer works, but I also want to let you know that I get a notification from Windows Defender SmartScreen preventing the app to run, due to it having an unknown publisher, and I thus had to click "more options" before I was able to run it.

My relevant specs:
Windows 10 Pro
Intel i7 x64

Crash when Delving into Binding Expression of ListView.ItemsSource that has errors

Message: Cannot set Expression. It is marked as 'NonShareable' and has already been used.
Stacktrace:
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Snoop.PropertyInspector.set_Target(Object value)
at Snoop.PropertyInspector.PushTarget(Object target)
at Snoop.PropertyInspector.HandleDelveBindingExpression(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.CommandManager.TransferEvent(IInputElement newSource, ExecutedRoutedEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Tried to delve into binding expression

Message: Cannot set Expression. It is marked as 'NonShareable' and has already been used.
Stacktrace:
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Snoop.PropertyInspector.set_Target(Object value)
at Snoop.PropertyInspector.PushTarget(Object target)
at Snoop.PropertyInspector.HandleDelveBindingExpression(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.CommandManager.TransferEvent(IInputElement newSource, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

When I clicked in the leftmost column next to Name in the Properties Tab, I got the following exception

Message: Object reference not set to an instance of an object.
Stacktrace:
at Snoop.PropertyGrid2.HandleSort(Object sender, ExecutedRoutedEventArgs args)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.GridViewColumnHeader.ClickImplement()
at System.Windows.Controls.GridViewColumnHeader.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.Controls.GridViewColumnHeader.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Unhandled Exception

I always sleep my computer before leaving the company and open at home. Probably the cause of the problem is related to this. The stack trace is here:

Message: Exception has been thrown by the target of an invocation.
Stacktrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at Microsoft.Win32.SystemEvents.SystemEventInvokeInfo.InvokeCallback(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

InnerException:

Message: Object reference not set to an instance of an object.
Stacktrace:
at Microsoft.VisualStudio.Editors.ResourceEditor.ResourceListView.OnSystemColorsChanged(EventArgs e)
at System.Windows.Forms.Control.OnSystemColorsChanged(EventArgs e)
at System.Windows.Forms.Control.OnSystemColorsChanged(EventArgs e)
at System.Windows.Forms.Control.UserPreferenceChanged(Object sender, UserPreferenceChangedEventArgs pref)

What does the Snoop logo imply?

snoop

The Snoop logo is a dog sniffing something. Clearly, Snoop is the dog doing the sniffing. By analogy, my app must be the object being sniffed. What does that say about my app?!

Download link at codeplex.com not working

Maybe it is a temporary issue, but here is a zipped copy of the binaries for anyone's convenience. Codeflex is entirely shut down in December 2017, so I assume any download links over there will be gone then as well.

NOTE: THESE ARE NOT THE OFFICIAL FILES!
Run at your own risk. They are based on the files uploaded at Chocolatey: https://chocolatey.org/packages/snoop
It does not have the .msi installer, but I'm sure that can be sourced somewhere too.

Snoop-2.8.0.zip

Issue with clipboard

I have changed a bool property SnapToDevicePixels few times in Snoop, and then Snoop raised an exception after I closed my WPF window.

Message: OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))
Stacktrace:
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
at System.Windows.Clipboard.Flush()
at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
at System.Windows.Clipboard.SetDataInternal(String format, Object data)
at System.Windows.Clipboard.SetText(String text, TextDataFormat format)
at System.Windows.Clipboard.SetText(String text)
at Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties()
at Snoop.SnoopUI.SnoopedWindowClosingHandler(Object sender, CancelEventArgs e)
at System.Windows.Window.OnClosing(CancelEventArgs e)
at System.Windows.Window.WmClose()
at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

When the WPF application I was attached to reloaded its data (and the visual tree likely was refreshed as well), Snoop triggered an exception that crashed the whole WPF app. Here is the stack trace:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Snoop.Shell.VisualTreeProviderExtensions.NodeName(VisualTreeItem item)
   at Snoop.Shell.VisualTreeProvider.GetTreeItem(String path)
   at Snoop.Shell.VisualTreeProvider.OnSyncSelectedItem(Object _)
   at System.Threading.TimerQueueTimer.CallCallbackInContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.TimerQueueTimer.CallCallback()
   at System.Threading.TimerQueueTimer.Fire()
   at System.Threading.TimerQueue.FireNextTimers()
   at System.Threading.TimerQueue.AppDomainTimerCallback()

Found a defect

Message: The visual tree has been changed during a 'VisualTreeChanged' event.
Stacktrace:
at System.Windows.Diagnostics.VisualDiagnostics.VerifyVisualTreeChangeCore(DependencyObject d)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.ClearValueCommon(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata)
at System.Windows.DependencyObject.ClearValue(DependencyPropertyKey key)
at System.Windows.BroadcastEventHelper.RemoveLoadedCallback(DependencyObject d, Object[] loadedPending)
at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
at MS.Internal.LoadedOrUnloadedOperation.DoWork()
at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
at System.Windows.Interop.HwndTarget.OnResize()
at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Crash when browser the visual tree

Message: 异常来自 HRESULT:0xD4B66448
Stacktrace:
在 MS.Win32.UnsafeNativeMethods.ITextStoreACPSink.OnLayoutChange(TsLayoutCode lcode, Int32 viewCookie)
在 System.Windows.Documents.TextStore.OnLayoutUpdated()
在 System.Windows.Documents.TextEditor.OnTextViewUpdatedWorker(Object o)
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Exception while diving in command binding expression

Message: Cannot set Expression. It is marked as 'NonShareable' and has already been used.
Stacktrace:
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Snoop.PropertyInspector.HandleDelveBindingExpression(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.CommandManager.TransferEvent(IInputElement newSource, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Potential memory leak in Injector.cpp

Hi Cory, I'm not sure this is a bug, though I'd like to point you to a potential issue in the injection code. As you may remember, I got inspired (read I copied/pasted) your injection code in my own Hawkeye2 project. While testing it, I added some more logging and also invoked GetLastError to make sure all the win32 api calls succeeded.
I noticed that calls to VirtualFreeEx were always failing with a 87 (invalid parameter) error code. Went to msdn and, given I understand it correctly, I modified my code to correctly release the memory allocated by VirtualAllocEx.

I think that in https://github.com/cplotts/snoopwpf/blob/master/ManagedInjector/Injector.cpp @ line 56

::VirtualFreeEx(hProcess, acmRemote, buffLen, MEM_RELEASE);

should be replaced with:

::VirtualFreeEx(hProcess, acmRemote, 0, MEM_RELEASE);

The corresponding fix in my own code is here:
https://github.com/odalet/Hawkeye2/blob/master/src/HawkeyeInjector/injector.cpp (line 219)

Hope this helps, regards.

Ambiguous match found error while choosing the "shows only visuals with binding errors"

Hi Everybody,

I've got the following exception when trying to choose "shows only visuals with binding errors" option. Have to say, I am snooping quite large and complex application. Dows anybody know anything about this error?

Message: Ambiguous match found.
Stacktrace:
   at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
   at System.Type.GetProperty(String name)
   at MS.Internal.ComponentModel.DependencyPropertyKind.get_IsDirect()
   at MS.Internal.ComponentModel.DependencyPropertyKind.get_IsAttached()
   at MS.Internal.ComponentModel.APCustomTypeDescriptor.GetProperties(Attribute[] attributes)
   at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultExtendedTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
   at System.ComponentModel.TypeDescriptor.GetPropertiesImpl(Object component, Attribute[] attributes, Boolean noCustomTypeDesc, Boolean noAttributes)
   at System.ComponentModel.TypeDescriptor.GetProperties(Object component, Attribute[] attributes)
   at Snoop.VisualItem.get_HasBindingError()
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.FilterBindings(VisualTreeItem node)
   at Snoop.SnoopUI.ProcessFilter()
   at Snoop.DelayedCall.Process(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

Screenshot function has some limitations with large DPIs

I tried 300 dpi (default) with a panel which measured 10560x859 and this exception was thrown. Maybe this could be handled more gracefully. It worked at 96dpi.

Message: Insufficient memory to continue the execution of the program. Stacktrace: at System.Windows.Media.Imaging.RenderTargetBitmap.FinalizeCreation() at System.Windows.Media.Imaging.RenderTargetBitmap..ctor(Int32 pixelWidth, Int32 pixelHeight, Double dpiX, Double dpiY, PixelFormat pixelFormat) at Snoop.VisualCaptureUtil.SaveVisual(Visual visual, Int32 dpi, String filename) at Snoop.ScreenshotDialog.HandleSave(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding) at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated) at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated) at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) at System.Windows.Controls.Primitives.ButtonBase.OnClick() at System.Windows.Controls.Button.OnClick() at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

InvalidOperationException while trying to clic on a control

Message: La propriété '[Unknown]' ne pointe pas vers un DependencyObject du chemin '(0).(1)[0].(2)'.
Stacktrace:
à System.Windows.Media.Animation.Storyboard.VerifyPathIsAnimatable(PropertyPath path)
à System.Windows.Media.Animation.Storyboard.ClockTreeWalkRecursive(Clock currentClock, DependencyObject containingObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehavior handoffBehavior, HybridDictionary clockMappings, Int64 layer)
à System.Windows.Media.Animation.Storyboard.ClockTreeWalkRecursive(Clock currentClock, DependencyObject containingObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehavior handoffBehavior, HybridDictionary clockMappings, Int64 layer)
à System.Windows.Media.Animation.Storyboard.BeginCommon(DependencyObject containingObject, INameScope nameScope, HandoffBehavior handoffBehavior, Boolean isControllable, Int64 layer)
à System.Windows.VisualStateGroup.StartNewThenStopOld(FrameworkElement element, Storyboard[] newStoryboards)
à System.Windows.VisualStateManager.GoToStateInternal(FrameworkElement control, FrameworkElement stateGroupsRoot, VisualStateGroup group, VisualState state, Boolean useTransitions)
à System.Windows.VisualStateManager.GoToStateCommon(FrameworkElement control, FrameworkElement stateGroupsRoot, String stateName, Boolean useTransitions)
à System.Windows.Controls.Primitives.ButtonBase.ChangeVisualState(Boolean useTransitions)
à System.Windows.Controls.Control.UpdateVisualState(Boolean useTransitions)
à System.Windows.Controls.Control.OnVisualStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
à System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
à System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
à System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
à System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
à System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
à System.Windows.DependencyObject.SetValue(DependencyPropertyKey key, Object value)
à System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action2 originChangedAction) à System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action2 originChangedAction)
à System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action2 originChangedAction) à System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList1 otherOrigins, DeferredElementTreeState& oldTreeState, Action`2 originChangedAction)
à System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, DeferredElementTreeState& oldTreeState)
à System.Windows.Input.MouseDevice.ChangeMouseOver(IInputElement mouseOver, Int32 timestamp)
à System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
à System.Windows.Input.InputManager.ProcessStagingArea()
à System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
à System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
à System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
à System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
à MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
à MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
à System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
à MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

[Question] .NET Framework 3.5 in snoop 2.10

In release notes you said that snooping WPF 3.5 application is deprecated. However, snoop itself requires .NET 3.5. Is it intentional? At the moment I don't have apps that require .NET 3.5 and when launched Snoop 2.10 it asked for .NET 3.5

Add release binaries to GitHub

Please add the Snoop binaries here on GitHub.
(I didn't spot the link to the blog download at first, and the CodePlex link appears to be blocked by Chrome.)
Thanks!

Crash with a Trigger using a Behavior<T> attached property

I just discovered the new release and immediately jumped on it !
The new Trigger Tab is a great addition but I found an issue that leads to a crash.
After some investigation I found that the exception occurs in ConditionItem.cs file because it cannot retrieve a DependencyPropertyDescriptor.

It can happen when the dependency property is an attached property of a Behavior<T>.
I could easily make a simple workaround on a local build for Snoop, but hope you can find a more elegant solution.

Finy by label content

Hi
Is there a property that I find or focus a control element by using label text data ?

example XAML:
Some Label context - Aloha

and I want to search like ''Aloha"

Is there any tab panel for this ?

OpenClipboard exception when closing Snoop

Hi Snoop team!

I've been using Snoop for a couple of weeks now, and I've suddenly started encountering this error when I try and close a Snoop window for my WPF application.

Exception:
Message: OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))
Stacktrace:
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
at System.Windows.Clipboard.Flush()
at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
at System.Windows.Clipboard.SetDataInternal(String format, Object data)
at System.Windows.Clipboard.SetText(String text, TextDataFormat format)
at System.Windows.Clipboard.SetText(String text)
at Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties()
at Snoop.SnoopUI.OnClosing(CancelEventArgs e)
at System.Windows.Window.WmClose()
at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

image

Please let me know if there's any info you need.

Thanks,

Chris Dusyk

OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))

While working with the Snoop WPF utility. Got this error very frequent.

Message: OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))
Stacktrace:
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
at System.Windows.Clipboard.Flush()
at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
at System.Windows.Clipboard.SetDataInternal(String format, Object data)
at System.Windows.Clipboard.SetText(String text, TextDataFormat format)
at System.Windows.Clipboard.SetText(String text)
at Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties()
at Snoop.SnoopUI.OnClosing(CancelEventArgs e)
at System.Windows.Window.WmClose()
at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Exception after target program has been closed

Message: Ошибка при вызове OpenClipboard (Исключение из HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))
Stacktrace:
в System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
в System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
в System.Windows.Clipboard.Flush()
в System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
в System.Windows.Clipboard.SetDataInternal(String format, Object data)
в System.Windows.Clipboard.SetText(String text, TextDataFormat format)
в System.Windows.Clipboard.SetText(String text)
в Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties()
в Snoop.SnoopUI.SnoopedWindowClosingHandler(Object sender, CancelEventArgs e)
в System.Windows.Window.OnClosing(CancelEventArgs e)
в System.Windows.Window.WmClose()
в System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Path Data values have wrong format

Hi,
snooping an application to get a given path geometry I stumbled over a behaviour I don't understand, but that might be a bug in Snoop:

The Data value of a WPF Path item is shown in Snoop as
F1M6;0C9,31371;0 12;2,68629 12;6 12;9,31371 9,31371;12 6;12 2,68629;12 -6,35783E-07;9,31371 -6,35783E-07;6 -6,35783E-07;2,68629 2,68629;0 6;0z M3;4L5;6 3;8 4;9 6;7 8;9 9;8 7;6 9;4 8;3 6;5 4;3 3;4z

This value cannot be used in XAML, VisualStudio raises an exception.

Replacing , by . and ; by , (in that order) fixed the problem.

Nevertheless: Is there some strange localization of the values taking place or similar?

Probably worth to know: Running Windows in German

Unhandled exception

Message: OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN)) Stacktrace: at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at System.Windows.Clipboard.Flush() at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy) at System.Windows.Clipboard.SetDataInternal(String format, Object data) at System.Windows.Clipboard.SetText(String text, TextDataFormat format) at System.Windows.Clipboard.SetText(String text) at Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties() at Snoop.SnoopUI.OnClosing(CancelEventArgs e) at System.Windows.Window.WmClose() at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Add options to prevent multiple dispatcher question and setting of owner on snoop windows

Hi,

I'd like to add options to prevent the multiple dispatcher question and setting of owner on snoop windows.

Currently the question for multiple dispatchers appears every time i want to attach snoop to one of my applications and i always answer with "no" because the application only has a progress/busy indicator window running in a separate dispatcher. Getting asked every time is quite annoying. ;-)

When snoop opens it's windows it sets the owner to the first appropriate window it is able to find. If your application has multiple windows this causes snoop to be in the background when the owner is in the background and snoop being in the foreground if the owner is in the foreground. This makes interacting with multiple windows difficult. It gets even worse when you minimize the owner as snoop is also minimized then.

To give users the options to decide what should happen, I'd like to add these two options to snoops main window. That way users can decide what should happen before attaching to their application.
These options would then be saved in snoops settings file so the user doesn't have to set the options every time.

These settings would then have to be transferred from snoop to the injector launcher, from there to the injector and from there to the target process.

I already tried a few ways to transfer these options and came to the conclusion that the easiest way would be:

  • Add the options to snoops settings class (for persistence)
  • Create a new class containing the options (for transient transport)
  • Before starting the injector launcher serialize the transient options to a temporary file and pass that file to the launcher
  • Pass the file path from the launcher to the injector
  • Pass the file path from the injector to the target process by adding it to the window message being sent to the injected process
  • De-serialize the settings from the temporary file and apply the options
  • Delete the temporary file (this would be done in snoops main process after the launcher is finished)

I therefore changed the data being sent via SendMessage from a string separated by "$" to the serialized data of some new transient data class which contains the data. This will also allow us, if we ever need to, pass more data from the injector to the target process.

The SendMessage data class looks like:

public ref class InjectorData : System::Object
{
	public:
		property System::String^ AssemblyName;
		property System::String^ ClassName;
		property System::String^ MethodName;

		property System::String^ SettingsFile;
};

The data class being serialized to disk looks like this:

public sealed class TransientSettingsData
{
    private static readonly XmlSerializer serializer = new XmlSerializer(typeof(TransientSettingsData));

    public TransientSettingsData()
    {
        this.SetWindowOwner = true;
        this.UseMultipleDispatcherMode = null;
    }

    public bool SetWindowOwner { get; set; }

    public bool? UseMultipleDispatcherMode { get; set; }

    public string WriteToFile()
    {
        var settingsFile = Path.GetTempFileName();

        using (var stream = new FileStream(settingsFile, FileMode.Create))
        {
            serializer.Serialize(stream, this);	                   
        }

        return settingsFile;
    }

    public static TransientSettingsData Load(string file)
    {
        using (var stream = new FileStream(file, FileMode.Open))
        {
            return (TransientSettingsData)serializer.Deserialize(stream);
        }
    }
}

What do you think about this @cplotts @MaciekRakowski ?

Snoop crash when application shutdown.

Message: OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))
Stacktrace:
在 System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
在 System.Windows.Clipboard.Flush()
在 System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
在 System.Windows.Clipboard.SetDataInternal(String format, Object data)
在 System.Windows.Clipboard.SetText(String text, TextDataFormat format)
在 System.Windows.Clipboard.SetText(String text)
在 Snoop.EditedPropertiesHelper.DumpObjectsWithEditedProperties()
在 Snoop.SnoopUI.SnoopedWindowClosingHandler(Object sender, CancelEventArgs e)
在 System.ComponentModel.CancelEventHandler.Invoke(Object sender, CancelEventArgs e)
在 System.Windows.Window.OnClosing(CancelEventArgs e)
在 System.Windows.Window.WmClose()
在 System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Snoop loads global resources from target app to snoop own window

Hi.

Just an FYI since I don't think it's a real issue:

When adding some "global" resource (App.xaml / Application.Resources / ...) , seems like Snoop is loading these resources as well, and applying all on Snoop main window.

See attached screenshot:
app with global resource

Thanks.

Keyboard events not passed to snoop UI window

I have a mixed WinForms and WPF app. During the initialization of the Winforms app I already initialize WPF:
new System.Windows.Application { ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown };

This results in that FindRoot in SnoopUI.xaml.cs thinks it's an WPF application:

if (Application.Current != null) { }

This prevents the execution of the else statement which enabled keyboard interop for modeless WPF windows in winforms applications: ElementHost.EnableModelessKeyboardInterop(this);

Why not move this code outside the else statement:

`
if (System.Windows.Forms.Application.OpenForms.Count > 0)
{
// this is windows forms -> wpf interop

            // call ElementHost.EnableModelessKeyboardInterop to allow the Snoop UI window
            // to receive keyboard messages. if you don't call this method,
            // you will be unable to edit properties in the property grid for windows forms interop.
            ElementHost.EnableModelessKeyboardInterop(this);
        }

`

The system cannot find the file specified

Could never get this application to work

Exception details:
System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at Snoop.Injector.Launch(IntPtr windowHandle, Assembly assembly, String className, String methodName) in D:\Programs\snoopwpf\Snoop\Injector.cs:line 69
at Snoop.WindowInfo.Snoop() in D:\Programs\snoopwpf\Snoop\AppChooser.xaml.cs:line 304


Environment

  • Snoop 2.10.0.0
  • Windows 6.1.7601
  • .NET Framework 4.0.30319.42000

Unhandled Exception when changing WPF Trace Level to Activity Tracing

Message: Requested value 'Activity Tracing' was not found.
Stacktrace:
at System.Enum.EnumResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument)
at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
at Snoop.DebugListenerTab.DebugListenerControl.comboBoxPresentationTraceLevel_SelectionChanged(Object sender, SelectionChangedEventArgs e)
at System.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.ComboBox.OnSelectionChanged(SelectionChangedEventArgs e)
at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List1 unselectedInfos, List1 selectedInfos)
at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo info, Boolean assumeInItemsCollection)
at System.Windows.Controls.ComboBox.NotifyComboBoxItemMouseUp(ComboBoxItem comboBoxItem)
at System.Windows.Controls.ComboBoxItem.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.