TIP 753: Windows auto_execok enhancements and reform

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Author:             Ashok P. Nadkarni <apnmbx-public@yahoo.com>
Tcl-Version:        9.1
State:              Draft
Type:               Project
Created:            2026-04-23
Tcl-Branch:         tip-753

Abstract

This TIP proposes changes and enhancements to auto_execok and exec on Windows and fixes some inconsistencies. Behavior on non-Windows platforms is mostly unaffected except for removal of caches. It also formally defines command behavior

See related tickets 4ab2ccc4a2, 1244733, e21fc32c2a, 1c6f6503d4, 4dc35e0c0c, 596936dd2d, 093353fedb and 4fae07ea8a

Specification

Changes to auto_execok

Elimination of auto_execs cache (all platforms)

Incompatibility

Currently, the auto_execok implementation maintains a cache mapping to resolved commands. This cache does not account for changes that impact resolution, such as the working directory, PATH environment variable etc. resulting in bugs.

The TIP proposes to eliminate this cache. This has a performance impact but exec'ing a process is an expensive operation in any case. Applications that do care can maintain their own cache instead.

This can be seen as an implementation issue but is included in this TIP because this cache is publically documented as auto_execs in the library.n manpage. Attempts to access this cache will result in an undefined variable error being raised.

Support for App Paths (Windows only)

Registered applications on Windows can be invoked directly without being present in the PATH. This is the modern recommended way to be able to invoke applications from outside their installation directory and followed by major applications. In 9.0, Tcl fails to find these applications.

% exec firefox
couldn't execute "firefox": no such file or directory
% auto_execok firefox
%

This TIP proposes to enhance auto_exec to support such applications.

% auto_execok firefox
{C:\Program Files\Mozilla Firefox\firefox.exe}

One limitation of this support is that while the underlying Windows mechanism allows modification of the process environment passed to the child process, this is not possible due to the lack of such a capability within both exec and the auto_execok to exec "interface".

Handling of PATHEXT extensions (Windows only)

The PATHEXT environment variable on Windows lists the filename extensions that are searched when looking for a program to execute. Currently auto_execok looks up this environment variable. For extensions other than ".com", ".exe", ".cmd" and ".bat", the returned command is not in a form that can be executed by exec directly. For example, the command

exec {*}[auto_execok myscript.vbs]

will fail.

This TIP fixes this by modifying auto_execok to return the command template in the registry for the extensions listed in PATHEXT. The format of the command template is ill-defined in practice, e.g. spaces in the executable path are not always quoted. Therefore certain heuritics will be employed for parsing the template and performing substitutions on the template before returning it.

One limitation is that the mechanism only works when all arguments are trailing arguments and not interspersed with constant tokens. This is a limitation of the Tcl's auto_exec and exec interface, not specific to this TIP.

This is also really a bug fix. However, it is change in behaviour in that auto_execok for an extension in PATHEXT will now return a list that can be exec'ed rather than the path to a file. Applications (unlikely) that relied on this will break.

Changes to exec

Changes to search path (Windows only)

In 9.0 and earlier, the exec search path, by design, prioritized the order of extensions over the order of directories in the PATH environment variable. For example, given files C:\a\b\foo.bat, C:\x\y\foo.exe and PATH of C:\a\b;C:\x\y, exec foo would invoke C:\x\y\foo.exe as .exe was prioritized over .bat. This is inconsistent with both auto_execok and Windows user expectations.

As per this TIP, directories will be searched in the order listed below. In each directory, files will be checked in the order of the passed file name followed by the name with extensions ".com", ".exe", ".bat" and ".com" in that order (this is the same order of extensions as 9.0).

The directory search order, consistent with auto_execok is

  • the directory of the process executable

  • the current working directory

  • the Windows system directory

  • the Windows directory

  • directories in PATH with empty elements skipped

This order is independent of the Windows "safe search" registry setting which controls the inclusion the current working directory from the search order.

NOTE

Unlike auto_execok, exec in 9.0 only searches for exe, com and bat. The extensions in PATHEXT are not examined. This will not be changed for 9.1 either as exec is a mapping into CreateProcess while auto_execok maps into Windows' more general notion of a program or document.

Changes to file executable (Windows only)

Windows executables are not compelled to have a .exe extension. This TIP modifies the file executable command, which is documented to check the extension(s), to also return true if the content is a PE32 executable format.

Maintained inconsistencies

The following inconsistency present in 9.0 is maintained by intent as I am unsure whether it should be changed.

Windows exec searches PATH when passed a relative path unlike Unix exec and auto_execok on all platforms. Windows itself exhibits this difference between CreateProcess, `ShellExecute** and the command line.

Reminders (for self)

Should built-ins be checked only at the end?

Should registry "safe search" settings be followed to include/exclude working directory?

Make order exe, bat, cmd, com, "" ? Or at least move .com to the end? Check what is actually passed to ApplicationType.

Implementation notes

Implementation is in the tip-753 branch.

Copyright

This document has been placed in the public domain.

History