Skip to content

Commit ab84034

Browse files
authored
Updates to .NET 10 (#4)
Bumps the target framework to .NET 10. Updates dependencies to be compatible with .NET 10. Suppresses CA1416, CA1873, and CA1515 warnings. Uses generic method Marshal.PtrToStructure<T> to improve code maintainability.
1 parent aae4d33 commit ab84034

10 files changed

Lines changed: 87 additions & 70 deletions

File tree

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ dotnet_diagnostic.CS1998.severity = suggestion
1717
# Reason: it could be too verbose to use it everywhere, but this is a good reminder
1818
dotnet_diagnostic.CA1848.severity = suggestion
1919

20+
# CA1416: This call site is reachable on all platforms. 'User32.MSLLHOOKSTRUCT.pt' is only supported on: 'windows'.
21+
dotnet_diagnostic.CA1416.severity = none
22+
23+
# CA1873: Evaluation of this argument may be expensive and unnecessary if logging is disabled
24+
# Reason: logging performance is not critical in our context, and this warning is too aggressive
25+
dotnet_diagnostic.CA1873.severity = none
26+
27+
# CA1515: Because an application's API isn't typically referenced from outside the assembly, types can be made internal
28+
dotnet_diagnostic.CA1515.severity = none
29+
2030
# CA1822: Member 'GetPagedResult' does not access instance data and can be marked as static
2131
# Reason: it may be more convenient to preserve a method as non-static
2232
dotnet_diagnostic.CA1822.severity = suggestion

.github/workflows/release.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ jobs:
1515

1616
steps:
1717
- name: Checkout
18-
uses: actions/checkout@v4
18+
uses: actions/checkout@v5
1919
with:
2020
fetch-depth: 0
2121

2222
- name: Install .NET
23-
uses: actions/setup-dotnet@v4
23+
uses: actions/setup-dotnet@v5
2424
with:
25-
dotnet-version: '8.0.x'
25+
dotnet-version: '10.0.x'
2626

2727
- name: Get branch and tag
2828
id: branch_name
@@ -51,9 +51,9 @@ jobs:
5151
- name: Build and package
5252
working-directory: ./WinSyncScroll
5353
run: |
54-
dotnet publish -c release -r win-x64 --framework net8.0-windows --self-contained
54+
dotnet publish -c release -r win-x64 --framework net10.0-windows --self-contained
5555
dotnet publish -c release -r win-x64 --framework net462
56-
7z a WinSyncScroll_win-x64_net8.0-windows.zip ./bin/release/net8.0-windows/win-x64/publish/*
56+
7z a WinSyncScroll_win-x64_net10.0-windows.zip ./bin/release/net10.0-windows/win-x64/publish/*
5757
7z a WinSyncScroll_win-x64_net462.zip ./bin/release/net462/win-x64/publish/*
5858
5959
- name: Publish
@@ -64,5 +64,5 @@ jobs:
6464
make_latest: ${{ steps.ref_info.outputs.MAKE_LATEST }}
6565
generate_release_notes: true
6666
files: |
67-
./WinSyncScroll/WinSyncScroll_win-x64_net8.0-windows.zip
67+
./WinSyncScroll/WinSyncScroll_win-x64_net10.0-windows.zip
6868
./WinSyncScroll/WinSyncScroll_win-x64_net462.zip

ShowWndProcMessages/ShowWndProcMessages.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>WinExe</OutputType>
5-
<TargetFrameworks>net462;net8.0-windows</TargetFrameworks>
5+
<TargetFrameworks>net462;net10.0-windows</TargetFrameworks>
66
<EnableWindowsTargeting>true</EnableWindowsTargeting>
77
<Nullable>enable</Nullable>
88
<ImplicitUsings>enable</ImplicitUsings>
@@ -12,9 +12,9 @@
1212

1313
<ItemGroup>
1414
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
15-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
16-
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.3" />
17-
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.1.1">
15+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
17+
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.1.2">
1818
<PrivateAssets>all</PrivateAssets>
1919
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2020
</PackageReference>

WinSyncScroll.sln

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 18
4+
VisualStudioVersion = 18.0.11205.157 d18.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
36
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinSyncScroll", "WinSyncScroll\WinSyncScroll.csproj", "{FB6EF979-B67D-4623-BA41-84E53056DFE0}"
47
EndProject
58
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowWndProcMessages", "ShowWndProcMessages\ShowWndProcMessages.csproj", "{01998BC3-C9BD-41CB-AA56-56097401DB2E}"
69
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6F91F047-0FBA-4CAD-83F9-6E6E2CF2B4E9}"
11+
ProjectSection(SolutionItems) = preProject
12+
.editorconfig = .editorconfig
13+
.gitignore = .gitignore
14+
global.json = global.json
15+
README.md = README.md
16+
EndProjectSection
17+
EndProject
718
Global
819
GlobalSection(SolutionConfigurationPlatforms) = preSolution
920
Debug|Any CPU = Debug|Any CPU
@@ -19,4 +30,10 @@ Global
1930
{01998BC3-C9BD-41CB-AA56-56097401DB2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
2031
{01998BC3-C9BD-41CB-AA56-56097401DB2E}.Release|Any CPU.Build.0 = Release|Any CPU
2132
EndGlobalSection
33+
GlobalSection(SolutionProperties) = preSolution
34+
HideSolutionNode = FALSE
35+
EndGlobalSection
36+
GlobalSection(ExtensibilityGlobals) = postSolution
37+
SolutionGuid = {669A0E66-A3F9-40FA-88EA-93F6C580DE5E}
38+
EndGlobalSection
2239
EndGlobal

WinSyncScroll/Services/MouseHook.cs

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -86,42 +86,34 @@ private LRESULT HookFunc(int code, WPARAM wParam, LPARAM lParam)
8686
|| wParam == WinApiConstants.WM_MOUSEHWHEEL
8787
|| wParam == WinApiConstants.WM_MOUSEMOVE))
8888
{
89-
var mouseLowLevelDataObj = Marshal.PtrToStructure(lParam, typeof(User32.MSLLHOOKSTRUCT));
90-
if (mouseLowLevelDataObj is null)
89+
var mouseLowLevelData = Marshal.PtrToStructure<User32.MSLLHOOKSTRUCT>(lParam);
90+
91+
if (mouseLowLevelData.IsInjected())
92+
{
93+
// we have nothing to do with injected events
94+
_logger.LogTrace("Ignoring injected mouse event: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
95+
}
96+
else if (_sourceRect is not null
97+
&& WinApiUtils.PointInRect(_sourceRect, mouseLowLevelData.pt.X, mouseLowLevelData.pt.Y)
98+
&& (wParam == WinApiConstants.WM_MOUSEWHEEL
99+
|| wParam == WinApiConstants.WM_MOUSEHWHEEL))
100+
{
101+
// we should process scroll events in this area
102+
_logger.LogTrace("Mouse scroll event in source rect: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
103+
HookEvents.Writer.TryWrite(new MouseMessageInfo(wParam, mouseLowLevelData));
104+
}
105+
else if (IsPreventRealScrollEventsActive()
106+
&& _targetRect is not null
107+
&& WinApiUtils.PointInRect(_targetRect, mouseLowLevelData.pt.X, mouseLowLevelData.pt.Y))
91108
{
92-
_logger.LogWarning("Failed to marshal {NameOfLParam} to {NameOfStruct}", nameof(lParam), nameof(User32.MSLLHOOKSTRUCT));
109+
// prevent the system from passing the message to the rest of the hook chain or the target window procedure
110+
_logger.LogTrace("Preventing real scroll events in target rect: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
111+
return (LRESULT)1;
93112
}
94-
else
113+
else if (wParam == WinApiConstants.WM_MOUSEWHEEL
114+
|| wParam == WinApiConstants.WM_MOUSEHWHEEL)
95115
{
96-
var mouseLowLevelData = (User32.MSLLHOOKSTRUCT)mouseLowLevelDataObj;
97-
98-
if (mouseLowLevelData.IsInjected())
99-
{
100-
// we have nothing to do with injected events
101-
_logger.LogTrace("Ignoring injected mouse event: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
102-
}
103-
else if (_sourceRect is not null
104-
&& WinApiUtils.PointInRect(_sourceRect, mouseLowLevelData.pt.X, mouseLowLevelData.pt.Y)
105-
&& (wParam == WinApiConstants.WM_MOUSEWHEEL
106-
|| wParam == WinApiConstants.WM_MOUSEHWHEEL))
107-
{
108-
// we should process scroll events in this area
109-
_logger.LogTrace("Mouse scroll event in source rect: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
110-
HookEvents.Writer.TryWrite(new MouseMessageInfo(wParam, mouseLowLevelData));
111-
}
112-
else if (IsPreventRealScrollEventsActive()
113-
&& _targetRect is not null
114-
&& WinApiUtils.PointInRect(_targetRect, mouseLowLevelData.pt.X, mouseLowLevelData.pt.Y))
115-
{
116-
// prevent the system from passing the message to the rest of the hook chain or the target window procedure
117-
_logger.LogTrace("Preventing real scroll events in target rect: {MouseLowLevelData}", mouseLowLevelData.ToLogString());
118-
return (LRESULT)1;
119-
}
120-
else if (wParam == WinApiConstants.WM_MOUSEWHEEL
121-
|| wParam == WinApiConstants.WM_MOUSEHWHEEL)
122-
{
123-
_logger.LogTrace("Ignoring mouse event: {MouseLowLevelData}, because it is not in source rect: {SourceRect}", mouseLowLevelData.ToLogString(), _sourceRect.ToLogString());
124-
}
116+
_logger.LogTrace("Ignoring mouse event: {MouseLowLevelData}, because it is not in source rect: {SourceRect}", mouseLowLevelData.ToLogString(), _sourceRect.ToLogString());
125117
}
126118
}
127119

WinSyncScroll/Services/WinApiService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public ICollection<WindowInfo> ListWindows()
4343
continue;
4444
}
4545

46-
var (_, processId, errorCode) = PInvoke.GetWindowThreadProcessId(windowHandle);
46+
var (_, processId, errorCode) = PInvoke.GetWindowInfo(windowHandle);
4747
if (processId == 0 || errorCode != 0)
4848
{
4949
_logger.LogWarning("Failed to get process ID for window with handle {WindowHandle}", windowHandle);

WinSyncScroll/ViewModels/MainViewModel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public sealed partial class MainViewModel : IDisposable
8585
private int _smCxScreen;
8686
private int _smCyScreen;
8787

88-
private static readonly int SizeOfInput = Marshal.SizeOf(typeof(INPUT));
88+
private static readonly int SizeOfInput = Marshal.SizeOf<INPUT>();
8989

9090
public MainViewModel(
9191
ILogger<MainViewModel> logger,
@@ -266,7 +266,7 @@ private async Task RunMouseEventProcessingLoopAsync(
266266
if (_options.Value.IsStrictProcessIdCheckEnabled)
267267
{
268268
var actualSourceWindowHwnd = PInvoke.WindowFromPoint(new Point(sourceEventX, sourceEventY));
269-
var (_, actualSourceProcessId, _) = PInvoke.GetWindowThreadProcessId(actualSourceWindowHwnd);
269+
var (_, actualSourceProcessId, _) = PInvoke.GetWindowInfo(actualSourceWindowHwnd);
270270

271271
if (actualSourceProcessId != Source.ProcessId)
272272
{
@@ -292,7 +292,7 @@ private async Task RunMouseEventProcessingLoopAsync(
292292
if (_options.Value.IsStrictProcessIdCheckEnabled)
293293
{
294294
var actualTargetWindowHwnd = PInvoke.WindowFromPoint(new Point(targetX, targetY));
295-
var (_, actualTargetWindowProcessId, _) = PInvoke.GetWindowThreadProcessId(actualTargetWindowHwnd);
295+
var (_, actualTargetWindowProcessId, _) = PInvoke.GetWindowInfo(actualTargetWindowHwnd);
296296

297297
if (actualTargetWindowProcessId != Target.ProcessId)
298298
{

WinSyncScroll/WinSyncScroll.csproj

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>WinExe</OutputType>
5-
<TargetFrameworks>net462;net8.0-windows</TargetFrameworks>
5+
<TargetFrameworks>net462;net10.0-windows</TargetFrameworks>
66
<EnableWindowsTargeting>true</EnableWindowsTargeting>
77
<Nullable>enable</Nullable>
88
<ImplicitUsings>enable</ImplicitUsings>
@@ -25,7 +25,7 @@
2525
<PropertyGroup>
2626
<!-- Code analysis -->
2727
<EnableNETAnalyzers>true</EnableNETAnalyzers>
28-
<AnalysisLevel>8-all</AnalysisLevel>
28+
<AnalysisLevel>10-all</AnalysisLevel>
2929

3030
<!-- Warnings and errors -->
3131
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -42,55 +42,53 @@
4242
</PackageReference>
4343
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
4444
<PackageReference Include="FontAwesome6.Svg" Version="2.5.1" />
45-
<PackageReference Include="Meziantou.Analyzer" Version="2.0.188">
45+
<PackageReference Include="Meziantou.Analyzer" Version="2.0.253">
4646
<PrivateAssets>all</PrivateAssets>
4747
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4848
</PackageReference>
49-
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.3" />
50-
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.3" />
51-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
52-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
53-
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.3" />
54-
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.3" />
55-
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="9.0.3" />
56-
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.13.2">
49+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
50+
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
51+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
52+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
53+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
54+
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" />
55+
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="10.0.0" />
56+
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
5757
<PrivateAssets>all</PrivateAssets>
5858
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5959
</PackageReference>
60-
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
60+
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.242">
6161
<PrivateAssets>all</PrivateAssets>
6262
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
6363
</PackageReference>
64-
<PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="61.0.15-preview" />
65-
<PackageReference Include="Microsoft.Windows.WDK.Win32Metadata" Version="0.12.8-experimental" />
6664
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
67-
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
65+
<PackageReference Include="NLog.Extensions.Logging" Version="6.1.0" />
6866
<PackageReference Include="PolySharp" Version="1.15.0">
6967
<PrivateAssets>all</PrivateAssets>
7068
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
7169
</PackageReference>
72-
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.1.1">
70+
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.1.2">
7371
<PrivateAssets>all</PrivateAssets>
7472
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
7573
</PackageReference>
76-
<PackageReference Include="Roslynator.Analyzers" Version="4.13.1">
74+
<PackageReference Include="Roslynator.Analyzers" Version="4.14.1">
7775
<PrivateAssets>all</PrivateAssets>
7876
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
7977
</PackageReference>
80-
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.13.1">
78+
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1">
8179
<PrivateAssets>all</PrivateAssets>
8280
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
8381
</PackageReference>
84-
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
82+
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.15.0.120848">
8583
<PrivateAssets>all</PrivateAssets>
8684
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
8785
</PackageReference>
8886
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
8987
<PrivateAssets>all</PrivateAssets>
9088
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
9189
</PackageReference>
92-
<PackageReference Include="System.Threading.Channels" Version="9.0.3" />
93-
<PackageReference Include="Vanara.PInvoke.User32" Version="4.1.1" />
90+
<PackageReference Include="System.Threading.Channels" Version="10.0.0" />
91+
<PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" />
9492
</ItemGroup>
9593

9694
<ItemGroup>

WinSyncScroll/Windows.Win32/PInvoke.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Windows.Win32;
99

1010
internal partial class PInvoke
1111
{
12-
internal static unsafe (uint ThreadId, uint ProcessId, int errorCode) GetWindowThreadProcessId(HWND hwnd)
12+
internal static unsafe (uint ThreadId, uint ProcessId, int errorCode) GetWindowInfo(HWND hwnd)
1313
{
1414
uint lpdwProcessId;
1515
uint* lpdwProcessIdPtr = &lpdwProcessId;

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "8.0.0",
3+
"version": "10.0.0",
44
"rollForward": "latestFeature",
55
"allowPrerelease": false
66
}

0 commit comments

Comments
 (0)