Fix Auto-injection packaging for release artifacts - #18
miloszkukla wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves the reliability of Auto-injection when publishing/packing the server by ensuring the native bootstrapper and the full .NET Framework Inspector dependency closure are built, included in artifacts, and validated in CI. It also extends the Shared/Inspector target framework matrix (net472 + tests) and adjusts runtime dependency resolution behavior for injected .NET Framework scenarios.
Changes:
- Build x64/Win32 native bootstrappers in CI and fail artifact/package creation if required Auto-injection payload files are missing.
- Package the full .NET Framework Inspector dependency closure under both
native/x64andnative/x86, and add an MSBuild validation target to prevent silent omission during Publish/Pack. - Expand multi-targeting to include
net472and add Shared-level regression tests (Shared models + IPC serializer envelope).
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| WpfVisualTreeMcp.sln | Adds the new Shared test project to the solution. |
| tests/WpfVisualTreeMcp.Shared.Tests/WpfVisualTreeMcp.Shared.Tests.csproj | New multi-targeted (net8/net472/net48) test project for Shared. |
| tests/WpfVisualTreeMcp.Shared.Tests/SharedModelsTests.cs | Adds basic Shared model shape/regression tests. |
| tests/WpfVisualTreeMcp.Shared.Tests/IpcSerializerTests.cs | Adds regression tests for IPC envelope serialization/deserialization. |
| src/WpfVisualTreeMcp.Shared/WpfVisualTreeMcp.Shared.csproj | Adds net472 and ensures System.Text.Json package is included for .NET Framework TFMs. |
| src/WpfVisualTreeMcp.Server/WpfVisualTreeMcp.Server.csproj | Packages full net48 Inspector dependency closure per-arch and validates required injection payload before Publish/Pack; standardizes runtimeconfig name in package layout. |
| src/WpfVisualTreeMcp.Inspector/WpfVisualTreeMcp.Inspector.csproj | Adds net472 target and aligns explicit WPF references for net472/net48. |
| src/WpfVisualTreeMcp.Inspector/InspectorService.cs | Adds .NET Framework private dependency resolver hook for injected scenarios. |
| src/WpfVisualTreeMcp.Injector/WpfVisualTreeMcp.Injector.csproj | Simplifies Injector to target net8.0 only. |
| README.md | Updates docs to reflect Inspector multi-targeting and project structure. |
| CHANGELOG.md | Adds Unreleased entries describing Auto-injection packaging fixes. |
| .github/workflows/release.yml | Builds native bootstrapper and verifies publish + NuGet payload completeness in release workflow. |
| .github/workflows/build.yml | Builds native bootstrapper and verifies publish + NuGet payload completeness in CI build workflow. |
Suppressed comments (2)
src/WpfVisualTreeMcp.Inspector/InspectorService.cs:126
- Initialize() registers the dependency resolver only for NET48. With net472 now supported, this should be enabled for all .NET Framework builds so injected/self-hosted net472 Inspectors can resolve their co-located dependencies in processes without binding redirects.
#if NET48
RegisterDependencyResolver();
#endif
src/WpfVisualTreeMcp.Inspector/InspectorService.cs:141
- RegisterDependencyResolver() is guarded by #if NET48, which prevents the resolver (and its supporting fields) from being available to the net472 Inspector build. Guarding by NETFRAMEWORK keeps the behavior consistent across .NET Framework targets.
#if NET48
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| private bool _disposed; | ||
|
|
||
| private static readonly object _initLock = new(); | ||
| #if NET48 |
| │ ├── WpfVisualTreeMcp.Inspector/ # Injected DLL (.NET Framework 4.7.2/4.8 and .NET 8) | ||
| │ ├── WpfVisualTreeMcp.Injector/ # Managed injection logic (CreateRemoteThread; net48 + net8.0) |
|
Superseded by #22, which consolidates the full change set and incorporates the applicable review feedback. Closing this stacked PR to avoid duplicate review threads and workflow ambiguity. |
Important
This PR is stacked after #20. Merge #20 first, then this PR, using merge commits. Because GitHub cannot use a contributor-fork branch as the base of an upstream PR, this diff is temporarily cumulative; the shared commits have identical IDs and will disappear from this PR after #20 is merged. PR #19 follows this PR, then #21.
Summary
MAX_PATHin a NuGet tool installationRoot cause
The native
.vcxprojis not part ofWpfVisualTreeMcp.sln, sodotnet buildnever producedWpfInspectorBootstrapper.dll. The Server project then silently omitted it throughCondition="Exists(...)".The package also copied only
WpfVisualTreeMcp.Inspector.dllandWpfVisualTreeMcp.Shared.dll, excluding the .NET Framework Inspector's runtime dependencies. Copying those dependencies exposed an assembly-version mismatch normally handled by application binding redirects, which cannot be assumed for injection into arbitrary target processes.Finally, the custom CoreCLR runtimeconfig filename exceeded the legacy Win32 path limit inside the deeply nested NuGet tool store.
Validation
dotnet build WpfVisualTreeMcp.sln --configuration Release— 0 errors (existing cross-TFM warnings unchanged)dotnet test WpfVisualTreeMcp.sln --no-build --configuration Release— 74/74 passed before stacking Add .NET Framework 4.7.2 Inspector support #20WpfInspectorBootstrapper.dllPE outputs.nupkginto an isolated tool directory