From c07b53c12ed6b980e783f73352b89b4fe8288f9c Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sun, 26 Apr 2026 10:58:32 +0200 Subject: [PATCH 1/5] Support of .NET 10 --- .github/workflows/dotnet.yml | 9 ++++---- Directory.Build.props | 3 +++ Directory.Build.targets | 14 +++++++----- WinFormsComInterop/WinFormsComInterop.csproj | 3 ++- WinFormsComInterop/WinFormsComWrappers.cs | 22 ++++++++++++++++++- .../Ole32/Interop.IServiceProvider.cs | 3 ++- .../System.Windows.Forms.Primitives.csproj | 2 +- .../System.Windows.Forms.csproj | 2 +- .../SampleWindowsForms.csproj | 2 +- 9 files changed, 44 insertions(+), 16 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 50b4c35..dd49721 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,13 +13,14 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Setup .NET 6 & 7 & 8 + - name: Setup .NET 6 & 7 & 8 & 10 uses: actions/setup-dotnet@v3 with: dotnet-version: | - 6.0.427 - 7.0.120 - 8.0.403 + 6.0.428 + 7.0.410 + 8.0.420 + 10.0.203 - name: Restore dependencies run: dir "C:\Program Files\dotnet\\shared\Microsoft.WindowsDesktop.App\" - name: Restore dependencies diff --git a/Directory.Build.props b/Directory.Build.props index c8c5009..465c874 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,9 @@ + True True + True + True False $(DefineConstants);USE_WPF 0.5.0 diff --git a/Directory.Build.targets b/Directory.Build.targets index c8dcf6d..2d80688 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -2,19 +2,21 @@ C:\Program Files\dotnet\ $(NetCoreRoot) - $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\8.0.10\Accessibility.dll + $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\10.0.7\Accessibility.dll + $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\8.0.26\Accessibility.dll $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\7.0.20\Accessibility.dll - $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\6.0.35\Accessibility.dll + $(DotnetInstallLocation)shared\Microsoft.WindowsDesktop.App\6.0.36\Accessibility.dll - + $(AccessibilityLocation) - - - + + + + \ No newline at end of file diff --git a/WinFormsComInterop/WinFormsComInterop.csproj b/WinFormsComInterop/WinFormsComInterop.csproj index 9bcffd4..d53f1a5 100644 --- a/WinFormsComInterop/WinFormsComInterop.csproj +++ b/WinFormsComInterop/WinFormsComInterop.csproj @@ -1,7 +1,8 @@  - net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0;net10.0 + true true enable diff --git a/WinFormsComInterop/WinFormsComWrappers.cs b/WinFormsComInterop/WinFormsComWrappers.cs index fc08a73..0e16c12 100644 --- a/WinFormsComInterop/WinFormsComWrappers.cs +++ b/WinFormsComInterop/WinFormsComWrappers.cs @@ -221,6 +221,7 @@ static WinFormsComWrappers() wrapperEntry->Vtable = vtbl; return wrapperEntry; } +#if !NET10_0_OR_GREATER private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) { @@ -229,18 +230,29 @@ private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) primitives::Windows.Win32.System.Com.IServiceProvider.PopulateVTable((primitives::Windows.Win32.System.Com.IServiceProvider.Vtbl*)vtblRaw); vtbl = (System.IntPtr)vtblRaw; } +#endif #endif private static ComInterfaceEntry* CreateAccessibleObjectEntry() { CreatePrimitivesIRawElementProviderSimpleProxyVtbl(out var rawElementProviderSimpleVtbl); +#if !NET10_0_OR_GREATER CreatePrimitivesIServiceProviderProxyVtbl(out var serviceProviderVtbl); +#endif - var comInterfaceEntryMemory = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(WinFormsComWrappers), sizeof(ComInterfaceEntry) * 2); + var comInterfaceEntryMemory = RuntimeHelpers.AllocateTypeAssociatedMemory( + typeof(WinFormsComWrappers), + sizeof(ComInterfaceEntry) +#if !NET10_0_OR_GREATER + * 2 +#endif + ); var wrapperEntry = (ComInterfaceEntry*)comInterfaceEntryMemory.ToPointer(); wrapperEntry[0].IID = IID_IRawElementProviderSimple; wrapperEntry[0].Vtable = rawElementProviderSimpleVtbl; +#if !NET10_0_OR_GREATER wrapperEntry[1].IID = IID_IServiceProvider; wrapperEntry[1].Vtable = serviceProviderVtbl; +#endif return wrapperEntry; } #if !NET8_0_OR_GREATER @@ -430,6 +442,14 @@ private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) } #endif +#if !NET10_0_OR_GREATER + if (obj is System.Runtime.InteropServices.Marshalling.ComObject) + { + count = 1; + return formsFileDialogEventsEntry; + } +#endif + throw new NotImplementedException(); } diff --git a/facades/System.Windows.Forms.Primitives/Ole32/Interop.IServiceProvider.cs b/facades/System.Windows.Forms.Primitives/Ole32/Interop.IServiceProvider.cs index 3423b73..36c36aa 100644 --- a/facades/System.Windows.Forms.Primitives/Ole32/Interop.IServiceProvider.cs +++ b/facades/System.Windows.Forms.Primitives/Ole32/Interop.IServiceProvider.cs @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET8_0_OR_GREATER +#if NET10_0_OR_GREATER +#elif NET8_0_OR_GREATER namespace Windows.Win32.System.Com; using global::System; using global::System.CodeDom.Compiler; diff --git a/facades/System.Windows.Forms.Primitives/System.Windows.Forms.Primitives.csproj b/facades/System.Windows.Forms.Primitives/System.Windows.Forms.Primitives.csproj index 94f5341..be8c82e 100644 --- a/facades/System.Windows.Forms.Primitives/System.Windows.Forms.Primitives.csproj +++ b/facades/System.Windows.Forms.Primitives/System.Windows.Forms.Primitives.csproj @@ -1,7 +1,7 @@ - net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0;net10.0 true 6.0.0.0 6.0.0.0 diff --git a/facades/System.Windows.Forms/System.Windows.Forms.csproj b/facades/System.Windows.Forms/System.Windows.Forms.csproj index 94f5341..be8c82e 100644 --- a/facades/System.Windows.Forms/System.Windows.Forms.csproj +++ b/facades/System.Windows.Forms/System.Windows.Forms.csproj @@ -1,7 +1,7 @@ - net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0;net10.0 true 6.0.0.0 6.0.0.0 diff --git a/samples/SampleWindowsForms/SampleWindowsForms.csproj b/samples/SampleWindowsForms/SampleWindowsForms.csproj index 12cbdca..bb1b152 100644 --- a/samples/SampleWindowsForms/SampleWindowsForms.csproj +++ b/samples/SampleWindowsForms/SampleWindowsForms.csproj @@ -3,7 +3,7 @@ WinExe - net8.0-windows + net10.0-windows True enable <_SuppressWinFormsTrimError>true From 754d5e55e8df8cd57b76faad066028e7022e3dc4 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sun, 26 Apr 2026 11:03:54 +0200 Subject: [PATCH 2/5] Update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 2e44195..91c6bce 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.200", + "version": "10.0.203", "allowPrerelease": true, "rollForward": "major" } From c4a5929eb3d2c24f84b349bb79aaca29a01ffaf9 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sun, 26 Apr 2026 12:06:21 +0200 Subject: [PATCH 3/5] f --- WinFormsComInterop/WinFormsComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WinFormsComInterop/WinFormsComWrappers.cs b/WinFormsComInterop/WinFormsComWrappers.cs index 0e16c12..9872a57 100644 --- a/WinFormsComInterop/WinFormsComWrappers.cs +++ b/WinFormsComInterop/WinFormsComWrappers.cs @@ -442,7 +442,7 @@ private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) } #endif -#if !NET10_0_OR_GREATER +#if NET10_0_OR_GREATER if (obj is System.Runtime.InteropServices.Marshalling.ComObject) { count = 1; From 4ea4a4de3f76d82155bcc9d4de11f4291828405f Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sun, 26 Apr 2026 12:28:54 +0200 Subject: [PATCH 4/5] f --- WinFormsComInterop/WinFormsComWrappers.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WinFormsComInterop/WinFormsComWrappers.cs b/WinFormsComInterop/WinFormsComWrappers.cs index 9872a57..98a342c 100644 --- a/WinFormsComInterop/WinFormsComWrappers.cs +++ b/WinFormsComInterop/WinFormsComWrappers.cs @@ -60,6 +60,9 @@ public unsafe partial class WinFormsComWrappers : ComWrappers #if !NET8_0_OR_GREATER static ComWrappers.ComInterfaceEntry* formsFileDialogEventsEntry; #endif +#if NET10_0_OR_GREATER + static ComWrappers.ComInterfaceEntry* formsFileDialogEventsEntry; +#endif #if !NET7_0_OR_GREATER static ComWrappers.ComInterfaceEntry* enumVariantEntry; #endif @@ -128,6 +131,9 @@ static WinFormsComWrappers() formsWebBrowserEventEntry = CreateWebBrowserEventEntry(); formsFileDialogEventsEntry = CreateFileDialogEventsEntry(); #endif +#if NET10_0_OR_GREATER + formsFileDialogEventsEntry = CreateFileDialogEventsEntry(); +#endif #if USE_WPF oleDropTargetEntry = CreateOleDropTargetEntry(); winbaseTfContextEntry = CreateWinbaseITfContextEntry(); From 35f707b36d2820026fd9bf2ad9b9f57a267889cf Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sun, 26 Apr 2026 17:04:36 +0200 Subject: [PATCH 5/5] Attempt to build --- WinFormsComInterop/WinFormsComWrappers.cs | 25 ++++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/WinFormsComInterop/WinFormsComWrappers.cs b/WinFormsComInterop/WinFormsComWrappers.cs index 98a342c..d24d84b 100644 --- a/WinFormsComInterop/WinFormsComWrappers.cs +++ b/WinFormsComInterop/WinFormsComWrappers.cs @@ -61,7 +61,7 @@ public unsafe partial class WinFormsComWrappers : ComWrappers static ComWrappers.ComInterfaceEntry* formsFileDialogEventsEntry; #endif #if NET10_0_OR_GREATER - static ComWrappers.ComInterfaceEntry* formsFileDialogEventsEntry; + static ComWrappers.ComInterfaceEntry* comObjectEntry; #endif #if !NET7_0_OR_GREATER static ComWrappers.ComInterfaceEntry* enumVariantEntry; @@ -132,7 +132,7 @@ static WinFormsComWrappers() formsFileDialogEventsEntry = CreateFileDialogEventsEntry(); #endif #if NET10_0_OR_GREATER - formsFileDialogEventsEntry = CreateFileDialogEventsEntry(); + comObjectEntry = CreateComObjectEntry(); #endif #if USE_WPF oleDropTargetEntry = CreateOleDropTargetEntry(); @@ -333,6 +333,19 @@ private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) } #endif +#if NET10_0_OR_GREATER + private static ComInterfaceEntry* CreateComObjectEntry() + { + CreatePrimitivesIOleClientSiteProxyVtbl(out var vtbl); + + var comInterfaceEntryMemory = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(WinFormsComWrappers), sizeof(ComInterfaceEntry) * 1); + var wrapperEntry = (ComInterfaceEntry*)comInterfaceEntryMemory.ToPointer(); + wrapperEntry->IID = IID_IOleClientSite; + wrapperEntry->Vtable = vtbl; + return wrapperEntry; + } +#endif + #if !NET7_0_OR_GREATER private static ComInterfaceEntry* CreateEnumVariantEntry() { @@ -448,14 +461,6 @@ private static void CreatePrimitivesIServiceProviderProxyVtbl(out IntPtr vtbl) } #endif -#if NET10_0_OR_GREATER - if (obj is System.Runtime.InteropServices.Marshalling.ComObject) - { - count = 1; - return formsFileDialogEventsEntry; - } -#endif - throw new NotImplementedException(); }