From a600c6e0d45ef91941da6d180760be0edd6069e4 Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Mon, 5 May 2025 13:37:22 +0900 Subject: [PATCH 1/2] Init --- src/Files.App.CsWin32/NativeMethods.txt | 5 ++ .../Storables/WindowsStorage/STATask.cs | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/Files.App.CsWin32/NativeMethods.txt b/src/Files.App.CsWin32/NativeMethods.txt index aee2e82f99b3..527c154cfb43 100644 --- a/src/Files.App.CsWin32/NativeMethods.txt +++ b/src/Files.App.CsWin32/NativeMethods.txt @@ -226,3 +226,8 @@ _SICHINTF RoGetAgileReference IQueryInfo QITIPF_FLAGS +CreateEvent +SetEvent +CoWaitForMultipleObjects +CWMO_FLAGS +INFINITE diff --git a/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs b/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs index 29a4a6819e61..a8a3f483bd60 100644 --- a/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs +++ b/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs @@ -2,6 +2,9 @@ // Licensed under the MIT License. using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.System.Com; +using Windows.Win32.Security; namespace Files.App.Storage { @@ -143,5 +146,60 @@ public static Task Run(Func func) return tcs.Task; } + + public static Task RunAsSync(Func> func) + { + HANDLE hEventHandle = default; + + unsafe + { + hEventHandle = PInvoke.CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, default); + } + + var tcs = new TaskCompletionSource(); + + Thread thread = + new(async () => + { + PInvoke.OleInitialize(); + + try + { + tcs.SetResult(await func()); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + finally + { + PInvoke.SetEvent(hEventHandle); + PInvoke.OleUninitialize(); + } + }) + { + IsBackground = true, + Priority = ThreadPriority.Normal + }; + + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + + unsafe + { + HANDLE* pEventHandles = stackalloc HANDLE[1]; + pEventHandles[0] = hEventHandle; + uint dwIndex = 0u; + + PInvoke.CoWaitForMultipleObjects( + (uint)CWMO_FLAGS.CWMO_DEFAULT, + PInvoke.INFINITE, + 1u, + pEventHandles, + &dwIndex); + } + + return tcs.Task; + } } } From c682f2ae294d561794fd21089ba317d11a196175 Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Mon, 5 May 2025 19:35:18 +0900 Subject: [PATCH 2/2] Init --- .../Storables/WindowsStorage/STATask.cs | 76 ++++++++----------- .../Helpers/Win32/Win32PInvoke.Methods.cs | 14 ---- src/Files.App/Program.cs | 28 +------ 3 files changed, 33 insertions(+), 85 deletions(-) diff --git a/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs b/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs index a8a3f483bd60..357487b875d1 100644 --- a/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs +++ b/src/Files.App.Storage/Storables/WindowsStorage/STATask.cs @@ -147,57 +147,43 @@ public static Task Run(Func func) return tcs.Task; } - public static Task RunAsSync(Func> func) + public unsafe static Task RunAsSync(Action action) { - HANDLE hEventHandle = default; + Debug.Assert(Thread.CurrentThread.GetApartmentState() is ApartmentState.STA); - unsafe - { - hEventHandle = PInvoke.CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, default); - } + HANDLE hEventHandle = PInvoke.CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, default); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); - Thread thread = - new(async () => + Task.Run(() => + { + try { - PInvoke.OleInitialize(); - - try - { - tcs.SetResult(await func()); - } - catch (Exception ex) - { - tcs.SetException(ex); - } - finally - { - PInvoke.SetEvent(hEventHandle); - PInvoke.OleUninitialize(); - } - }) + action(); + tcs.SetResult(); + } + catch (Exception ex) { - IsBackground = true, - Priority = ThreadPriority.Normal - }; - - thread.SetApartmentState(ApartmentState.STA); - thread.Start(); - - unsafe - { - HANDLE* pEventHandles = stackalloc HANDLE[1]; - pEventHandles[0] = hEventHandle; - uint dwIndex = 0u; - - PInvoke.CoWaitForMultipleObjects( - (uint)CWMO_FLAGS.CWMO_DEFAULT, - PInvoke.INFINITE, - 1u, - pEventHandles, - &dwIndex); - } + tcs.SetException(ex); + } + finally + { + PInvoke.SetEvent(hEventHandle); + } + }); + + HANDLE* pEventHandles = stackalloc HANDLE[1]; + pEventHandles[0] = hEventHandle; + uint dwIndex = 0u; + + PInvoke.CoWaitForMultipleObjects( + (uint)CWMO_FLAGS.CWMO_DEFAULT, + PInvoke.INFINITE, + 1u, + pEventHandles, + &dwIndex); + + PInvoke.CloseHandle(hEventHandle); return tcs.Task; } diff --git a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs index 9af7345111ec..87a2fe5ac018 100644 --- a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs +++ b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs @@ -81,15 +81,6 @@ public static extern int GetDpiForWindow( IntPtr hwnd ); - [DllImport("ole32.dll")] - public static extern uint CoWaitForMultipleObjects( - uint dwFlags, - uint dwMilliseconds, - ulong nHandles, - IntPtr[] pHandles, - out uint dwIndex - ); - [DllImport("shell32.dll")] public static extern IntPtr SHBrowseForFolder( ref BROWSEINFO lpbi @@ -135,11 +126,6 @@ public static extern uint WaitForMultipleObjectsEx( bool bAlertable ); - [DllImport("api-ms-win-core-synch-l1-2-0.dll", SetLastError = true)] - public static extern bool ResetEvent( - IntPtr hEvent - ); - [DllImport("api-ms-win-core-synch-l1-2-0.dll", SetLastError = true)] public static extern uint WaitForSingleObjectEx( IntPtr hHandle, diff --git a/src/Files.App/Program.cs b/src/Files.App/Program.cs index 6d7807095797..96b16b3af2d0 100644 --- a/src/Files.App/Program.cs +++ b/src/Files.App/Program.cs @@ -9,7 +9,6 @@ using System.Text; using Windows.ApplicationModel.Activation; using Windows.Storage; -using static Files.App.Helpers.Win32PInvoke; namespace Files.App { @@ -21,9 +20,6 @@ namespace Files.App /// internal sealed class Program { - private const uint CWMO_DEFAULT = 0; - private const uint INFINITE = 0xFFFFFFFF; - public static Semaphore? Pool { get; set; } static Program() @@ -250,20 +246,10 @@ private static async void OnActivated(object? sender, AppActivationArguments arg /// public static void RedirectActivationTo(AppInstance keyInstance, AppActivationArguments args) { - IntPtr eventHandle = CreateEvent(IntPtr.Zero, true, false, null); - - Task.Run(() => + STATask.RunAsSync(() => { keyInstance.RedirectActivationToAsync(args).AsTask().Wait(); - SetEvent(eventHandle); }); - - _ = CoWaitForMultipleObjects( - CWMO_DEFAULT, - INFINITE, - 1, - [eventHandle], - out uint handleIndex); } public static void OpenShellCommandInExplorer(string shellCommand, int pid) @@ -273,20 +259,10 @@ public static void OpenShellCommandInExplorer(string shellCommand, int pid) public static void OpenFileFromTile(string filePath) { - IntPtr eventHandle = CreateEvent(IntPtr.Zero, true, false, null); - - Task.Run(() => + STATask.RunAsSync(() => { LaunchHelper.LaunchAppAsync(filePath, null, null).Wait(); - SetEvent(eventHandle); }); - - _ = CoWaitForMultipleObjects( - CWMO_DEFAULT, - INFINITE, - 1, - [eventHandle], - out uint handleIndex); } } }