Skip to content

Remove net48 as a direct build target#1829

Merged
shimat merged 7 commits intomainfrom
remove_direct_net48
Mar 1, 2026
Merged

Remove net48 as a direct build target#1829
shimat merged 7 commits intomainfrom
remove_direct_net48

Conversation

@shimat
Copy link
Owner

@shimat shimat commented Feb 28, 2026

Summary

Drop .NET Framework 4.8 from the explicit TargetFrameworks list in OpenCvSharp, OpenCvSharp.Extensions, and the test/nuget projects. The library continues to be usable from .NET Framework 4.6.1+ via the netstandard2.0 target, which NuGet resolves automatically.

OpenCvSharp.WpfExtensions retains net48 for now because WPF depends on framework assemblies (PresentationCore etc.) that cannot be expressed through a netstandard target.

New target frameworks

Project Before After
OpenCvSharp netstandard2.0; netstandard2.1; net48; net8.0 netstandard2.0; netstandard2.1; net8.0
OpenCvSharp.Extensions net48; netstandard2.0; netstandard2.1; net8.0 netstandard2.0; netstandard2.1; net8.0
OpenCvSharp.WpfExtensions net48; net8.0-windows unchanged
Test / nuget packaging projects included net48 net48 removed

Code changes

Removed #if DOTNET_FRAMEWORK / #if NET48 / #if NETFRAMEWORK branches

  • NativeMethods.cs – removed SuppressUnmanagedCodeSecurity, SecurityPermission attribute, and Environment.OSVersion.Platform-based OS detection
  • WindowsLibraryLoader.cs – removed AppDomain.CurrentDomain.BaseDirectory fallback, System.Web.HttpContext.Current ASP.NET hack, and Assembly.GetExecutingAssembly() branch; IsDotNetCore() now always returns the runtime-detection path
  • Win32API.csCharSet constant simplified to CharSet.Unicode unconditionally
  • OpenCVException.cs / OpenCvSharpException.cs – removed BinaryFormatter serialization constructor and GetObjectData override; removed now-unused using System.Runtime.Serialization

Simplified #if DOTNET_FRAMEWORK || NETSTANDARD2_0#if NETSTANDARD2_0

  • All 24 Vec*.cs struct files (GetHashCode fallback for missing HashCode.Combine)
  • NativeMethods.csStringUnmanagedTypeNotWindows constant (UnmanagedType.LPStr fallback, still needed for netstandard2.0)

Test cleanup

  • AppDomainTest.cs – deleted (entire file was #if NET48; AppDomain.CreateDomain is not supported on .NET Core)
  • FileDownloader.cs – collapsed to the HttpClient branch
  • ImgCodecsTest.cs – use AsSpan()[100..^100] and File.Move(..., true) unconditionally
  • XPhotoTest.cs – removed WinForms-based OpenFileDialog sample test
  • VideoCaptureTest.cs, VideoWriterTest.cs – removed #if NETFRAMEWORK class guards (tests now always compile and run)
  • WindowsLibraryLoaderTest.cs – removed NET48 branch; assert always true

CI / tooling

  • windows.yml – changed test steps from -f net48 to -f net8.0 / -f net8.0-windows
  • Packer.cs (ReleaseMaker) – removed net48 entry from dllFiles dictionary and XML file list
  • nuget/OpenCvSharp4.runtime.win*.csproj – removed build/net48 package path entry

Documentation

  • README.md – updated supported framework description; .NET Framework users are directed to use the netstandard2.0 path

Impact on existing consumers

Consumer Impact
.NET 8+ projects No change
.NET Standard 2.0 / 2.1 projects No change
.NET Framework 4.6.1–4.8 projects (non-WPF) No change – NuGet resolves netstandard2.0 automatically
.NET Framework 4.8 WPF projects using OpenCvSharp4.WpfExtensions No change – WpfExtensions still targets net48 directly
.NET Framework projects using OpenCvSharp4.Windows meta-package No change – meta-package still lists net48 as a TFM so WpfExtensions is pulled in transitively

Breaking changes

None for end users. The netstandard2.0 binary is functionally equivalent to what the net48 binary provided (minus legacy serialization constructors that were only meaningful with BinaryFormatter, which is itself removed in .NET 9+).

Summary by CodeRabbit

  • Documentation

    • Updated framework support to .NET 8.0+, .NET Standard 2.1 and 2.0; README clarifies x64-only native bindings.
    • Added workspace/settings and repository guidance including UTF-8 with BOM enforcement.
  • Refactor

    • Removed .NET Framework 4.8 targets and associated legacy interop/serialization and platform-detection fallbacks.
    • Simplified CI/workflows and packaging to x64-only outputs.
  • Tests

    • Removed NET48/AppDomain-specific tests and adjusted Windows-only test expectations.

@shimat shimat self-assigned this Feb 28, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 780f4a3 and 5e270e1.

📒 Files selected for processing (15)
  • .github/workflows/windows.yml
  • README.md
  • nuget/OpenCvSharp4.Windows.Slim.csproj
  • nuget/OpenCvSharp4.Windows.csproj
  • nuget/OpenCvSharp4.runtime.win.csproj
  • nuget/OpenCvSharp4.runtime.win.props
  • nuget/OpenCvSharp4.runtime.win.slim.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.props
  • src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj
  • test/OpenCvSharp.Tests.Windows/OpenCvSharp.Tests.Windows.csproj
  • test/OpenCvSharp.Tests/FileDownloader.cs
  • test/OpenCvSharp.Tests/OpenCvSharp.Tests.csproj
  • test/OpenCvSharp.Tests/imgcodecs/ImgCodecsTest.cs
  • test/OpenCvSharp.Tests/videoio/VideoCaptureTest.cs
  • tool/OpenCvSharp.ReleaseMaker/Packer.cs

📝 Walkthrough

Walkthrough

This PR removes .NET Framework 4.8 support and related NETFRAMEWORK conditionals, consolidates targets to .NET Standard 2.0/2.1 and .NET 8.0, drops x86 Windows native packaging, simplifies platform/PInvoke logic, updates CI/workflows and packaging, and removes or adjusts framework-specific tests and serialization code.

Changes

Cohort / File(s) Summary
Configuration & Docs
​.github/copilot-instructions.md, ​.vscode/settings.json, README.md, ​.github/workflows/windows.yml
Added BOM/UTF‑8 guidance and VSCode setting; updated README to remove .NET Framework 4.8 from primary targets and document x64-only native packages; simplified Windows CI workflow and removed net48/x86 build branches.
Project/Package manifests
src/OpenCvSharp/OpenCvSharp.csproj, src/OpenCvSharp.Extensions/OpenCvSharp.Extensions.csproj, nuget/OpenCvSharp4.runtime.win.csproj, nuget/OpenCvSharp4.runtime.win.slim.csproj, nuget/OpenCvSharp4.Windows.csproj, nuget/OpenCvSharp4.Windows.Slim.csproj, nuget/OpenCvSharp4.runtime.win.props, nuget/OpenCvSharp4.runtime.win.slim.props, nuget/OpenCvSharp4.runtime.win...
Removed net48 targets and net48-specific packaging/content entries; updated package Titles to x64-only; removed x86 content entries from runtime props.
Native build / loader / PInvoke
src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods.cs, src/OpenCvSharp/Internal/PInvoke/Win32API.cs, src/OpenCvSharp/Internal/PInvoke/WindowsLibraryLoader.cs
Removed DOTNET_FRAMEWORK-specific security/charset branches and AppDomain-based resolution fallbacks; standardized CharSet/ platform detection and simplified library load probing.
Exception serialization
src/OpenCvSharp/Fundamentals/OpenCVException.cs, src/OpenCvSharp/Fundamentals/OpenCvSharpException.cs
Removed NETFRAMEWORK-only serialization constructors and GetObjectData override; dropped System.Runtime.Serialization usage.
HashCode conditional changes
src/OpenCvSharp/Modules/core/Struct/Vec/* (Vec2*/Vec3*/Vec4*/Vec6* files)
Narrowed GetHashCode preprocessor guards from `DOTNET_FRAMEWORK
Tests: removals & updates
test/OpenCvSharp.Tests/system/AppDomainTest.cs, test/OpenCvSharp.Tests/system/WindowsLibraryLoaderTest.cs, test/OpenCvSharp.Tests/videoio/VideoCaptureTest.cs, test/OpenCvSharp.Tests/videoio/VideoWriterTest.cs, test/OpenCvSharp.Tests/xphoto/XPhotoTest.cs, test/OpenCvSharp.Tests/FileDownloader.cs, test/OpenCvSharp.Tests/imgcodecs/ImgCodecsTest.cs, test/OpenCvSharp.Tests.Windows/OpenCvSharp.Tests.Windows.csproj
Deleted NET48 AppDomain isolation test and GUI-specific tests; removed NETFRAMEWORK guards making some tests unconditional; FileDownloader refactored to top-level class and non‑NET48 HttpClient path; added ffmpeg DLL copy entry to test csproj.
Release tooling
tool/OpenCvSharp.ReleaseMaker/Packer.cs, src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj
Removed net48 DLL/XML entries and x86 architecture mapping from release packer; minor encoding/BOM changes in some project files.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: removing net48 as a direct build target, which is the primary focus of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch remove_direct_net48

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/OpenCvSharp/Fundamentals/OpenCVException.cs (1)

6-8: ⚠️ Potential issue | 🟠 Major

[Serializable] now advertises a contract that was removed.

At line 6, the class is marked [Serializable], but lacks the required serialization constructor (SerializationInfo, StreamingContext) and GetObjectData() method. The custom properties (Status, FuncName, ErrMsg, FileName, Line) will not be serialized with binary serialization, causing data loss for consumers still using BinaryFormatter or .NET Framework with netstandard2.0. Either remove the [Serializable] attribute or restore serialization members conditionally where compatibility is required.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/OpenCvSharp/Fundamentals/OpenCVException.cs` around lines 6 - 8, The
OpenCVException class is marked [Serializable] but lacks the required
serialization constructor and GetObjectData, so its custom properties (Status,
FuncName, ErrMsg, FileName, Line) won't be preserved; either remove the
[Serializable] attribute from class OpenCVException, or restore full
binary-serialization support by adding the protected constructor
OpenCVException(SerializationInfo info, StreamingContext context) that reads
those properties and override GetObjectData(SerializationInfo info,
StreamingContext context) to write them, and if you need conditional compilation
for modern runtimes wrap the serialization members with the appropriate
target-framework `#if` (e.g., NETSTANDARD2_0 || NETFRAMEWORK) guards so the
attribute and methods are present only where binary serialization compatibility
is required.
🧹 Nitpick comments (1)
src/OpenCvSharp/Modules/core/Struct/Vec/Vec6w.cs (1)

7-9: Pre-existing documentation typo: "4-Tuple" should be "6-Tuple".

The XML doc comment on line 8 says "4-Tuple of ushort" but this struct is Vec6w, a 6-tuple. This is not introduced by this PR, but worth fixing while you're here.

📝 Suggested fix
 /// <summary>
-/// 4-Tuple of ushort (System.UInt16)
+/// 6-Tuple of ushort (System.UInt16)
 /// </summary>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/OpenCvSharp/Modules/core/Struct/Vec/Vec6w.cs` around lines 7 - 9, Update
the XML summary for the Vec6w struct: change the incorrect "4-Tuple of ushort
(System.UInt16)" to "6-Tuple of ushort (System.UInt16)" in the Vec6w.cs file so
the documentation matches the struct name Vec6w and its semantics; locate the
summary tag above the Vec6w struct declaration and correct the tuple size text
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/windows.yml:
- Around line 182-188: CI currently only runs tests for net8.0-windows leaving
the declared net48 target unvalidated; add a Windows workflow step that builds
and runs the net48 target for the OpenCvSharp.WpfExtensions/tests. Modify the
"Test Windows-only functions" section (or add a new step near it) to run dotnet
restore/build/test for the net48 target (use -f net48 when invoking dotnet test
or dotnet build/test for the OpenCvSharp.Tests.Windows project) so both
net8.0-windows and net48 TFMs are exercised; ensure the step runs on the same
Windows runner and the workspace path (test/OpenCvSharp.Tests.Windows) is used
just like the existing test step.

In `@test/OpenCvSharp.Tests/FileDownloader.cs`:
- Around line 16-20: The response handling in FileDownloader should validate
status and dispose the response content stream: after obtaining httpResponse
from httpClient.Send (and before reading content) call
httpResponse.EnsureSuccessStatusCode() to throw on non-2xx, then obtain the
content stream via httpResponse.Content.ReadAsStream() inside a using block and
CopyTo the MemoryStream; keep using var memoryStream = new MemoryStream() and
return memoryStream.ToArray() but ensure the content stream is disposed by the
using around ReadAsStream() and that EnsureSuccessStatusCode() is invoked on
httpResponse.

---

Outside diff comments:
In `@src/OpenCvSharp/Fundamentals/OpenCVException.cs`:
- Around line 6-8: The OpenCVException class is marked [Serializable] but lacks
the required serialization constructor and GetObjectData, so its custom
properties (Status, FuncName, ErrMsg, FileName, Line) won't be preserved; either
remove the [Serializable] attribute from class OpenCVException, or restore full
binary-serialization support by adding the protected constructor
OpenCVException(SerializationInfo info, StreamingContext context) that reads
those properties and override GetObjectData(SerializationInfo info,
StreamingContext context) to write them, and if you need conditional compilation
for modern runtimes wrap the serialization members with the appropriate
target-framework `#if` (e.g., NETSTANDARD2_0 || NETFRAMEWORK) guards so the
attribute and methods are present only where binary serialization compatibility
is required.

---

Nitpick comments:
In `@src/OpenCvSharp/Modules/core/Struct/Vec/Vec6w.cs`:
- Around line 7-9: Update the XML summary for the Vec6w struct: change the
incorrect "4-Tuple of ushort (System.UInt16)" to "6-Tuple of ushort
(System.UInt16)" in the Vec6w.cs file so the documentation matches the struct
name Vec6w and its semantics; locate the summary tag above the Vec6w struct
declaration and correct the tuple size text accordingly.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95f438e and 780f4a3.

📒 Files selected for processing (47)
  • .github/copilot-instructions.md
  • .github/workflows/windows.yml
  • .vscode/settings.json
  • README.md
  • nuget/OpenCvSharp4.runtime.win.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.csproj
  • src/OpenCvSharp.Extensions/OpenCvSharp.Extensions.csproj
  • src/OpenCvSharp/Fundamentals/OpenCVException.cs
  • src/OpenCvSharp/Fundamentals/OpenCvSharpException.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods.cs
  • src/OpenCvSharp/Internal/PInvoke/Win32API.cs
  • src/OpenCvSharp/Internal/PInvoke/WindowsLibraryLoader.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2b.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2d.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2f.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2i.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2s.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec2w.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3b.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3d.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3f.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3i.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3s.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec3w.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4b.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4d.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4f.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4i.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4s.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec4w.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6b.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6d.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6f.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6i.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6s.cs
  • src/OpenCvSharp/Modules/core/Struct/Vec/Vec6w.cs
  • src/OpenCvSharp/OpenCvSharp.csproj
  • test/OpenCvSharp.Tests.Windows/OpenCvSharp.Tests.Windows.csproj
  • test/OpenCvSharp.Tests/FileDownloader.cs
  • test/OpenCvSharp.Tests/OpenCvSharp.Tests.csproj
  • test/OpenCvSharp.Tests/imgcodecs/ImgCodecsTest.cs
  • test/OpenCvSharp.Tests/system/AppDomainTest.cs
  • test/OpenCvSharp.Tests/system/WindowsLibraryLoaderTest.cs
  • test/OpenCvSharp.Tests/videoio/VideoCaptureTest.cs
  • test/OpenCvSharp.Tests/videoio/VideoWriterTest.cs
  • test/OpenCvSharp.Tests/xphoto/XPhotoTest.cs
  • tool/OpenCvSharp.ReleaseMaker/Packer.cs
💤 Files with no reviewable changes (5)
  • test/OpenCvSharp.Tests/videoio/VideoWriterTest.cs
  • tool/OpenCvSharp.ReleaseMaker/Packer.cs
  • test/OpenCvSharp.Tests/videoio/VideoCaptureTest.cs
  • src/OpenCvSharp/Internal/PInvoke/Win32API.cs
  • test/OpenCvSharp.Tests/system/AppDomainTest.cs

@shimat shimat marked this pull request as draft February 28, 2026 15:25
@shimat shimat marked this pull request as ready for review March 1, 2026 07:51
@shimat shimat merged commit b2f462b into main Mar 1, 2026
8 of 9 checks passed
@shimat shimat deleted the remove_direct_net48 branch March 1, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant