diff --git a/src/Reentry.App/NativeMethods.txt b/src/Reentry.App/NativeMethods.txt index ccb2e9f..ca6951a 100644 --- a/src/Reentry.App/NativeMethods.txt +++ b/src/Reentry.App/NativeMethods.txt @@ -14,8 +14,5 @@ QueryFullProcessImageNameW OpenProcess CloseHandle GetCurrentProcessId -SetWindowSubclass -RemoveWindowSubclass -DefSubclassProc ShowWindow UpdateWindow diff --git a/src/Reentry.App/Reentry.App.csproj b/src/Reentry.App/Reentry.App.csproj index cfa18a5..a06691f 100644 --- a/src/Reentry.App/Reentry.App.csproj +++ b/src/Reentry.App/Reentry.App.csproj @@ -20,6 +20,9 @@ Assets\reentry.ico x86;x64;ARM64 win-x86;win-x64;win-arm64 + + win-x64 true diff --git a/src/Reentry.App/Services/EndSessionHook.cs b/src/Reentry.App/Services/EndSessionHook.cs index 3b00066..cbb3b06 100644 --- a/src/Reentry.App/Services/EndSessionHook.cs +++ b/src/Reentry.App/Services/EndSessionHook.cs @@ -1,8 +1,5 @@ +using System.Runtime.InteropServices; using Microsoft.UI.Xaml; -using Windows.Win32; -using Windows.Win32.Foundation; -using Windows.Win32.UI.Controls; -using Windows.Win32.UI.WindowsAndMessaging; namespace Reentry.App.Services; @@ -14,11 +11,22 @@ public sealed class EndSessionHook : IDisposable { private const uint WmQueryEndSession = 0x0011; private const uint WmEndSession = 0x0016; + private const nuint SubclassId = 1; + private readonly Action _onEndSession; - private HWND _hwnd; - private SUBCLASSPROC? _proc; + private nint _hwnd; + private SubclassProc? _proc; private bool _attached; + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate nint SubclassProc( + nint hwnd, + uint msg, + nuint wParam, + nint lParam, + nuint idSubclass, + nuint refData); + public EndSessionHook(Action onEndSession) { _onEndSession = onEndSession; @@ -38,12 +46,12 @@ public void Attach(Window window) public void Attach(nint hwnd) { Detach(); - _hwnd = new HWND(hwnd); + _hwnd = hwnd; _proc = WndProc; - _attached = PInvoke.SetWindowSubclass(_hwnd, _proc, 1, 0); + _attached = SetWindowSubclass(_hwnd, _proc, SubclassId, 0); } - private LRESULT WndProc(HWND hwnd, uint msg, WPARAM wParam, LPARAM lParam, nuint id, nuint data) + private nint WndProc(nint hwnd, uint msg, nuint wParam, nint lParam, nuint id, nuint data) { if (msg is WmQueryEndSession or WmEndSession) { @@ -51,17 +59,39 @@ private LRESULT WndProc(HWND hwnd, uint msg, WPARAM wParam, LPARAM lParam, nuint catch { /* never block shutdown */ } } - return PInvoke.DefSubclassProc(hwnd, msg, wParam, lParam); + return DefSubclassProc(hwnd, msg, wParam, lParam); } private void Detach() { if (_attached && _proc is not null) { - PInvoke.RemoveWindowSubclass(_hwnd, _proc, 1); + RemoveWindowSubclass(_hwnd, _proc, SubclassId); _attached = false; } } public void Dispose() => Detach(); + + [DllImport("comctl32.dll", ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetWindowSubclass( + nint hWnd, + SubclassProc pfnSubclass, + nuint uIdSubclass, + nuint dwRefData); + + [DllImport("comctl32.dll", ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool RemoveWindowSubclass( + nint hWnd, + SubclassProc pfnSubclass, + nuint uIdSubclass); + + [DllImport("comctl32.dll", ExactSpelling = true)] + private static extern nint DefSubclassProc( + nint hWnd, + uint uMsg, + nuint wParam, + nint lParam); } diff --git a/src/Reentry.App/Services/Win32EventLogReader.cs b/src/Reentry.App/Services/Win32EventLogReader.cs index af8ea6a..5f772af 100644 --- a/src/Reentry.App/Services/Win32EventLogReader.cs +++ b/src/Reentry.App/Services/Win32EventLogReader.cs @@ -1,6 +1,7 @@ using System.Diagnostics.Eventing.Reader; using Reentry.Core.Abstractions; using Reentry.Core.Models; +using EventLogRecord = Reentry.Core.Models.EventLogRecord; namespace Reentry.App.Services; diff --git a/src/Reentry.App/Services/Win32ProcessProbe.cs b/src/Reentry.App/Services/Win32ProcessProbe.cs index a37279b..16873dc 100644 --- a/src/Reentry.App/Services/Win32ProcessProbe.cs +++ b/src/Reentry.App/Services/Win32ProcessProbe.cs @@ -20,7 +20,7 @@ public IReadOnlyList GetProcesses() try { started = process.StartTime.ToUniversalTime(); } catch { started = DateTimeOffset.UtcNow; } - list.Add(new LiveProcess(process.Id, exe, commandLine: null, started)); + list.Add(new LiveProcess(process.Id, exe, CommandLine: null, StartedUtc: started)); } catch { @@ -44,10 +44,10 @@ public IReadOnlyList GetVisibleWindows() return true; uint pid = 0; - _ = PInvoke.GetWindowThreadProcessId(hwnd, &pid); + PInvoke.GetWindowThreadProcessId(hwnd, &pid); var title = ReadTitle(hwnd); var exe = QueryImage((int)pid) ?? ""; - list.Add(new LiveWindow(hwnd.Value, (int)pid, title, exe, IsVisible: true)); + list.Add(new LiveWindow((long)hwnd.Value, (int)pid, title, exe, IsVisible: true)); return true; }, 0); return list;