Skip to content

fix: detect .bat and .cmd executables on Windows#81

Closed
ErikBjare wants to merge 1 commit intomasterfrom
dev/detect-bat-cmd-windows-exes
Closed

fix: detect .bat and .cmd executables on Windows#81
ErikBjare wants to merge 1 commit intomasterfrom
dev/detect-bat-cmd-windows-exes

Conversation

@ErikBjare
Copy link
Member

@ErikBjare ErikBjare commented Mar 24, 2022

Without this fix, aw-qt wouldn't detect modules as they end in .cmd or .bat (not sure which).

Reported here: https://discord.com/channels/755040852727955476/755334568977891348/956531050627104832

The user got the following output:

[INFO ]: Started aw-qt...  (aw_qt.main:31)
[INFO ]: Searching for bundled modules in: ['PATH \\activitywatch\\aw-qt\\aw_qt', PATH \\activitywatch\\aw-qt']  (aw_qt.manager:71)
[WARNING]: Found matching file but was not executable: PATH \activitywatch\aw-qt\aw-qt.spec  (aw_qt.manager:55)
[INFO ]: Found bundled modules:  (aw_qt.manager:77)
[INFO ]: Found system modules:  (aw_qt.manager:104)
[INFO ]:  - aw-client at PATH \venv\Scripts\aw-client.exe  (aw_qt.manager:24)
[ERROR]: Module aw-server not found  (aw_qt.manager:270)
[ERROR]: Module aw-watcher-afk not found  (aw_qt.manager:270)
[ERROR]: Module aw-watcher-window not found  (aw_qt.manager:270)
[ERROR]: Manager tried to start nonexistent module aw-server  (aw_qt.manager:260)
[ERROR]: Manager tried to start nonexistent module aw-watcher-afk  (aw_qt.manager:260)
[ERROR]: Manager tried to start nonexistent module aw-watcher-window  (aw_qt.manager:260)
[INFO ]: Creating trayicon...  (aw_qt.trayicon:206)
[INFO ]: Initialized aw-qt and trayicon succesfully  (aw_qt.trayicon:245) 

Not sure why aw-client becomes an .exe but aw-server etc becomes a .bat or .cmd

@ErikBjare
Copy link
Member Author

This PR didn't seem to work for the person who reported the issue. Needs manual testing.

@TimeToBuildBob
Copy link
Contributor

Re-checked this against the later issue history around #110 and the current manager.py state.

My read now is that this PR is still relevant:

So unless there was negative manual testing specifically against .cmd launchers, this still looks like an unfixed gap for the Windows source/venv workflow.

If helpful, I think the smallest next step would be to manually test exactly this matrix on Windows:

  1. install watchers into a venv so Scripts/ contains .cmd launchers
  2. start aw-qt from that environment
  3. verify _discover_modules_system() now finds those wrappers

If that passes, this PR (or a refreshed equivalent) still seems mergeable to me.

@ErikBjare
Copy link
Member Author

@greptileai review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 16, 2026

Greptile Summary

This PR fixes Windows module detection by adding .bat and .cmd as recognized executable extensions alongside .exe. It also includes minor formatting cleanup (docstring whitespace, quote style).

  • The core fix in is_executable correctly identifies .bat/.cmd files as executables on Windows, addressing the reported issue where aw-server, aw-watcher-afk, and aw-watcher-window were not found.
  • Bug: _filename_to_name (line 66) only strips .exe from filenames, so .bat/.cmd executables will have incorrect module names (e.g., aw-server.bat instead of aw-server), breaking autostart matching, module exclusion filters, and start-by-name lookups.

Confidence Score: 2/5

  • This PR has a logical bug that will cause module name mismatches on Windows, preventing autostart from working correctly for .bat/.cmd executables.
  • Score of 2 reflects that while the is_executable fix is correct, the incomplete _filename_to_name update means modules detected as .bat/.cmd will have wrong names, breaking downstream functionality (autostart, exclusion, start-by-name). The fix is straightforward but must be applied before merging.
  • aw_qt/manager.py_filename_to_name must also strip .bat and .cmd extensions

Important Files Changed

Filename Overview
aw_qt/manager.py Adds .bat and .cmd to Windows executable detection, but _filename_to_name does not strip these extensions — causing module name mismatches that break autostart, exclusion, and start-by-name lookups.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[File discovered: aw-server.bat] --> B{is_executable?}
    B -->|".bat" on Windows ✅| C[_filename_to_name]
    C --> D["Only strips .exe → name = 'aw-server.bat' ❌"]
    D --> E{autostart check: name in autostart_modules?}
    E -->|"'aw-server.bat' != 'aw-server' ❌"| F[Module not started]
    D --> G{exclusion check: name in exclude list?}
    G -->|"'aw-qt.bat' != 'aw-qt' ❌"| H[aw-qt not excluded from modules]
Loading

Comments Outside Diff (1)

  1. aw_qt/manager.py, line 65-66 (link)

    .bat/.cmd extensions not stripped from module names

    _filename_to_name only strips .exe, but with this PR, .bat and .cmd files are now valid executables. A file like aw-server.bat will produce a module name of aw-server.bat instead of aw-server. This will break:

    1. Autostart matching (line 273): autostart_modules contains names like aw-server, which won't match aw-server.bat.
    2. Module exclusion (line 244): aw-qt.bat and aw-client.bat won't be filtered out since the check compares against "aw-qt" and "aw-client".
    3. Manager.start() (line 257): module_name lookups will fail since stored names retain the extension.

Last reviewed commit: 860e801

@ErikBjare
Copy link
Member Author

@TimeToBuildBob Address review

@TimeToBuildBob
Copy link
Contributor

I dug into the remaining Greptile comment and it looks correct: this branch adds .bat / .cmd to is_executable(), but _filename_to_name() still strips only .exe, so discovered modules would keep names like aw-server.cmd and break autostart / exclusion / lookup matching.

I fixed that locally by updating _filename_to_name() to strip all three Windows launcher extensions:

def _filename_to_name(filename: str) -> str:
    if platform.system() == "Windows":
        for ext in (".exe", ".bat", ".cmd"):
            if filename.endswith(ext):
                return filename[: -len(ext)]
    return filename

Local validation:

  • verified aw-server.exe/.cmd/.bat -> aw-server with a small direct function check
  • confirmed the current branch head is still the older 860e801, so this specific bug is not yet fixed on the PR branch

I also created the fix commit locally as db7c37e (fix(manager): strip .bat and .cmd extensions on Windows), but couldn't push it because this checkout points at the upstream ActivityWatch/aw-qt remote and my token does not have push permission there (403).

So my updated read: the PR is conceptually right but still not merge-ready until this _filename_to_name() fix lands on the branch.

@ErikBjare
Copy link
Member Author

@TimeToBuildBob You fix it

@TimeToBuildBob
Copy link
Contributor

Fixed in #126.

Since I don't have push access to the ActivityWatch org branch, I pushed the fix to my fork and opened a new PR. The new PR includes both the original .bat/.cmd detection fix and the _filename_to_name() extension-stripping fix flagged by Greptile.

@ErikBjare
Copy link
Member Author

Merged #126, closing.

@ErikBjare ErikBjare closed this Mar 16, 2026
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.

2 participants