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..357487b875d1 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,46 @@ public static Task Run(Func func) return tcs.Task; } + + public unsafe static Task RunAsSync(Action action) + { + Debug.Assert(Thread.CurrentThread.GetApartmentState() is ApartmentState.STA); + + HANDLE hEventHandle = PInvoke.CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, default); + + var tcs = new TaskCompletionSource(); + + Task.Run(() => + { + try + { + action(); + tcs.SetResult(); + } + catch (Exception ex) + { + 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); } } }