CmdPal: Improve error handling and logging in activation process (#41344)

## Summary of the Pull Request

This PR makes passing arguments from a new instance to the existing one
more resilient:


- Fixes situations where `x-cmdpal://` links might not work as expected.
Instead of performing the intended action (e.g., `x-cmdpal://background`
or `x-cmdpal://settings`), they could incorrectly just summon the main
window.

- Refactors the `AppInstance.Activated` handler to be synchronous.  
- The handler blocks `AppInstance.RedirectActivationToAsync` in the
caller.
- If it runs asynchronously (or offloads work to another thread,
including the UI thread), the calling instance may exit too soon,
preventing the activation arguments from being read.

- Adds a timeout and ensures the semaphore is always released so the
application can exit gracefully under all conditions.

- Adjusts handling for cases where the source application exits before
passing arguments by lowering the log severity to **Warning** and
providing a clearer, more descriptive message.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] Closes: #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** yop
- [x] **Localization:** no need
- [x] **Dev docs:** no need
- [x] **New binaries:** none
- [x] **Documentation updated:** nope

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Tested with x-cmdpal://settings under normal conditions, and with CmdPal
deliberately slowed down to take its sweet time handling the arguments
(so the calling instance times out).
This commit is contained in:
Jiří Polášek
2025-09-02 22:39:59 +02:00
committed by GitHub
parent 7931f14bd5
commit d153f3473a
3 changed files with 57 additions and 13 deletions

View File

@@ -484,8 +484,13 @@ public sealed partial class MainWindow : WindowEx,
}
}
public void HandleLaunch(AppActivationArguments? activatedEventArgs)
public void HandleLaunchNonUI(AppActivationArguments? activatedEventArgs)
{
// LOAD BEARING
// Any reading and processing of the activation arguments must be done
// synchronously in this method, before it returns. The sending instance
// remains blocked until this returns; afterward it may quit, causing
// the activation arguments to be lost.
if (activatedEventArgs is null)
{
Summon(string.Empty);
@@ -522,9 +527,26 @@ public sealed partial class MainWindow : WindowEx,
}
catch (COMException ex)
{
// https://learn.microsoft.com/en-us/windows/win32/rpc/rpc-return-values
const int RPC_S_SERVER_UNAVAILABLE = -2147023174;
const int RPC_S_CALL_FAILED = 2147023170;
// Accessing properties activatedEventArgs.Kind and activatedEventArgs.Data might cause COMException
// if the args are not valid or not passed correctly.
Logger.LogError("COM exception when activating the application", ex);
if (ex.HResult is RPC_S_SERVER_UNAVAILABLE or RPC_S_CALL_FAILED)
{
Logger.LogWarning(
$"COM exception (HRESULT {ex.HResult}) when accessing activation arguments. " +
$"This might be due to the calling application not passing them correctly or exiting before we could read them. " +
$"The application will continue running and fall back to showing the Command Palette window.");
}
else
{
Logger.LogError(
$"COM exception (HRESULT {ex.HResult}) when activating the application. " +
$"The application will continue running and fall back to showing the Command Palette window.",
ex);
}
}
Summon(string.Empty);