Skip to content

perf: speed up Open Data Folder launch - #2009

Open
yijiy wants to merge 2 commits into
QL-Win:masterfrom
yijiy:perf/open-data-folder-launch
Open

yijiy wants to merge 2 commits into
QL-Win:masterfrom
yijiy:perf/open-data-folder-launch

Conversation

@yijiy

@yijiy yijiy commented Sep 23, 2026 •

Copy link
Copy Markdown

PR Checklist

  • Functionality has been tested, no obvious bugs
  • Code style follows project conventions
  • Documentation/comments updated (not applicable; no user-facing strings or documented options changed)

Brief Description of Changes

Open Data Folder now asks the Windows shell to open the data folder
directly instead of explicitly starting explorer.exe:

Process.Start(new ProcessStartInfo(SettingHelper.LocalDataPath)
{
    UseShellExecute = true,
    Verb = "open",
})

This is the same shell open request as ShellExecuteW(..., "open", folder, ...),
following the reviewer's suggestion. The previous implementation started a
temporary Explorer stub process that forwarded the request to a separate
Explorer factory process. With the shell open request, the already-running
Explorer process handles the folder directly. The net change is a single
5-line edit to the tray menu command, with no COM or P/Invoke code.

When the data folder is already open, the existing window is brought to the
front instead of opening a duplicate window.

Related Issue (if any)

Fixes #2008

Additional Notes

Performance validation

The operation was measured from the physical tray-menu click until Explorer
displayed the exact QuickLook data-folder path in a visible, responsive window
and accepted a click on a file in that folder. The folder was not open before
each measured click; Explorer was allowed to reuse a window it had prepared in
the background.

All three variants were built from the same base revision and run in the same
predeclared session order on the same machine:

Variant Measured runs Median Range
Original explicit explorer.exe launch 3 6467 ms 5272-6626 ms
Earlier revision of this PR (Shell.Application.Explore) 6 1414 ms 1297-2550 ms
This PR (shell open) 3 1424 ms 1038-1459 ms

The shell open version reduced the median by about 78% compared with the
original launch, matching the earlier Explore revision with simpler code.
All 12 measured operations passed the exact-path, visibility, responsiveness,
and click checks. The original launch started a new Explorer process for every
operation; both new variants were handled by the existing Explorer process.

With the folder already open, clicking Open Data Folder again:

  • original launch: opened a second window after about 2.4 s;
  • shell open: brought the existing window to the front in about 0.14 s.

A representative ETW trace of the original launch (zero lost events) showed:

  • temporary Explorer stub process start at +37 ms
  • Explorer factory process start at +1047 ms
  • first Explorer view loaded at +3026 ms
  • approximately 31 ms of QuickLook UI-thread sampled CPU (0.85%), so the
    delay was not CPU work in QuickLook

These are path-free summaries from one machine running a Windows 11 Insider
build, not a fleet-wide benchmark or formal statistical study. Absolute times
vary with machine state; the comparison is between variants measured in the
same session sequence. The first click after starting QuickLook was slower and
more variable for all variants and is not included in the table. Two planned
sessions ended before any measured operation because of test-harness input
problems. They were retained and not rerun, which is why two variants have
three runs.

Build validation

QuickLook\QuickLook.csproj built successfully in Release configuration.

@sourcery-ai

sourcery-ai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The tray menu's Open Data Folder action now invokes Explorer through a temporary Shell.Application COM object, allowing the existing Windows shell to handle the request directly and avoiding the previous explorer.exe stub/forwarding path. The COM object is deterministically released, and validation reports an 81.6% median launch-time reduction with successful exact-path behavior and a clean Release build.

Sequence diagram for faster Open Data Folder launch

sequenceDiagram
    actor User
    participant Tray as TrayIconManager
    participant COM as Shell.Application
    participant Explorer as Windows Shell Explorer

    User->>Tray: Open Data Folder
    Tray->>COM: CreateInstance
    Tray->>COM: InvokeMember Explore(LocalDataPath)
    COM->>Explorer: Open data folder
    Explorer-->>User: Display responsive data-folder window
    Tray->>COM: FinalReleaseComObject
Loading

File-Level Changes

Change Details Files
Route the tray menu action through the Windows Shell COM automation API instead of launching explorer.exe explicitly.
  • Replace the Process.Start command with an OpenDataFolder handler.
  • Resolve and instantiate Shell.Application, then invoke Explore with the configured data path.
  • Release the temporary COM object in a finally block and report unavailable/failed COM setup.
QuickLook/TrayIconManager.cs
Validate that the new launch path substantially reduces folder-opening latency without changing the requested destination behavior.
  • Compare five warm runs for the old and new implementations using exact-path, visibility, and responsiveness checks.
  • Record an 81.6% median improvement and summarize ETW observations for the baseline path.
PR description
Confirm the project still builds cleanly after the implementation change.
  • Build QuickLook.csproj in Release configuration with zero warnings and errors.
PR description

Assessment against linked issues

Issue Objective Addressed Explanation
#2008 Make the Open Data Folder tray-menu action open QuickLook's data folder promptly in File Explorer. ✅
#2008 Avoid the slow explicit explorer.exe child-process launch and use the existing Windows shell to handle the folder request, while properly releasing the temporary COM object. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="QuickLook/TrayIconManager.cs" line_range="122-145" />
<code_context>
         _icon.IsVisible = false;
     }

+    private static void OpenDataFolder()
+    {
+        var shellType = Type.GetTypeFromProgID("Shell.Application");
+        if (shellType == null)
+            throw new InvalidOperationException("Shell.Application is unavailable.");
+
+        var shell = Activator.CreateInstance(shellType);
+        if (shell == null)
+            throw new InvalidOperationException("Unable to create Shell.Application.");
+
+        try
+        {
+            shellType.InvokeMember(
+                "Explore",
+                BindingFlags.InvokeMethod,
+                null,
+                shell,
+                [SettingHelper.LocalDataPath]);
+        }
+        finally
+        {
</code_context>
<issue_to_address>
**issue (broader_impact):** When Shell.Application is unregistered, blocked by COM policy, or its Explore call fails, the tray command throws and no folder is opened because the new implementation has no fallback to the previous explorer.exe launch.

**Triggers:** When COM activation or the Shell.Application Explore invocation fails on a machine where explorer.exe itself is still available.

**Suggested fix:** Catch COM activation/invocation failures and fall back to `Process.Start("explorer.exe", SettingHelper.LocalDataPath)` instead of propagating the exception to the UI error handler.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: QuickLook/TrayIconManager.cs:145


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread QuickLook/TrayIconManager.cs Outdated
@emako

emako commented Sep 23, 2026

Copy link
Copy Markdown
Member

According to AI analysis, my solution is more compatible and stable:

https://github.com/emako/FileSystemLauncher/blob/master/src/FileSystemLauncher/Polyfill/Launcher.cs#L66C9-L66C95

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@yijiy

yijiy commented Sep 23, 2026

Copy link
Copy Markdown
Author

@emako Inspired by your approach. Now it's simpler with same perf benefit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Open Data Folder takes several seconds to open Explorer

2 participants