-
Notifications
You must be signed in to change notification settings - Fork 2
Profiling a Plugin Run
Capture a real execution of your plug-in from Dataverse, download it, and replay it locally against
the exact context the platform passed in — no live org needed to re-run it, and no Trace() archaeology.
Every screenshot on this page is taken from the automated end-to-end suite while it drives the real UI, so what you see is what the extension actually does. The control being used in each step is outlined in orange. (The environment name and URL are blanked out; you will see your own there.)
Preview feature. Plug-in debugging ships behind
dataverse-powertools.previewFeatures, off by default. Tick Preview features in the panel footer before the Debugging block appears. Sign-off checklist: #224.
| You need | Why |
|---|---|
| A connected environment | The profiler runs in the org, not on your machine |
| A deployed plug-in with a registered step | You can only profile a step that exists and is enabled |
| Windows, for Profile next run | The capture tool is .NET Framework. On macOS/Linux, capture in the Plugin Registration Tool and use Download a run instead |
| The Plugin Profiler solution | The extension offers to install it for you the first time |
Everything is in the Debugging block of the plug-in card. Active profiles underneath shows anything currently being profiled — worth knowing about, because a step stays disabled while it is profiled.

An assembly can register many steps, so the first decision is always which step. Two routes, differing only in how you pick.
Profile next run starts a capture for this component. If more than one step is profilable it first asks "Profile which plugin step?"; with exactly one it goes straight on.

Above every [CrmPluginRegistration(...)] attribute sits a Profile: Off / Profile: On CodeLens.
Clicking it profiles that step — the registration you are looking at — so there is no picker to answer.
This is the quickest route when you are already in the code, and the label doubles as an at-a-glance
indicator of which steps are armed.

Once profiling starts, the label flips to Profile: On:

Stop profiling from the Active profiles list, not the lens. Clicking Profile: On to stop does not currently work — it reports "No deployed step matches …" and profiling stays on, leaving your step disabled (#251). Use the stop button in the card's Active profiles block instead.
Use either route above. The extension enables profiling on the step and, for package-deployed plug-ins,
first populates the assembly content the profiler needs — Dataverse leaves that empty for pac/NuGet
packages, which is why profiling a package plug-in used to be impossible. The output shows
[Profiler] Started profiling … (panel button) or [Profiler] Profiling ON for … (CodeLens).
The extension waits while you make the thing happen that fires your step — create the record, run the flow, press the button in the app. Then press Continue.

An asynchronous step runs in a background job, so give it a few seconds after the trigger.
Continue lists the captured executions. Tick the one you want — it is a multi-select, so you can take several at once.

The chosen profile is saved to profiles/ in your component folder.
Replay & debug generates a unit test that replays the captured context through your plug-in, plus a
small shared harness (DvptProfileReplay.cs) in your test project.

With more than one profile in profiles/, it asks "Replay which profile?" first.

It decodes the .profile, rebuilds the IPluginExecutionContext the platform passed in, and calls your
plug-in's Execute in-process — no child AppDomain and no live org — so it runs anywhere dotnet test
runs, including CI.
Run it like any other test: the Testing side bar, Run Tests on the plug-in card, or dotnet test.
Green means the captured production context replayed through your code without throwing.
Debugging it (breakpoints) needs the C# extension — the Testing view's Debug action launches a
coreclrsession, whichms-dotnettools.csharpprovides. Note that Run/Debug Test at Cursor and the gutter icons do not currently work for plug-in tests (#252); use the Testing view's buttons.
- Enable profiling — the Plugin Profiler clones your step and disables the original, so executions route through the profiler.
- Capture — your trigger fires the profiled step; the profiler persists the execution context.
-
Download — the extension fetches the persisted profile into
profiles/. -
Generate — it writes a test that decodes the profile (base64 → deflate → report XML →
PluginExecutionContext) and invokes your plug-in against it. - Stop profiling — the clone is removed and your original step is re-enabled.
Step 5 is the one to remember: a step left profiled stays disabled, so it will not fire at all until profiling is stopped.
"N step(s) are registered for … but all are DISABLED" — profiling was left on. Stop it from the Active profiles list and the step comes back. (Before 1.0.2 this said "No registered plugin steps to profile — deploy your plugin and register a step first", which was impossible advice for a step you already had.)
"No steps registered for assembly …" — the deployed assembly name does not match this project, or the
step never registered. Check the [CrmPluginRegistration] attribute and redeploy with Build & deploy
package.
Nothing captured — an asynchronous step may not have finished, or the trigger did not match the step's message/table filter. The profiler only captures what actually fires.
- Debugging Plugins — the overview, trace logs, and the macOS/Linux route
- Plugins — the project type itself