I find myself now with like 5 different TD installs because I’m maintaining old projects/deployments.
On installation in Windows, we install to C://Program Files/Derivative/Touchdesigner/ and only when there are multiple parallel builds does the install folder get a suffix .2023.12600.
Is there a way to force this suffix even if we’re installing Touchdesigner for the first time?
I’m trying to handle versions and locate the right one to a specific TOE/project, and always have to make an edge case of "what if all you have is an unversioned install folder name.
Is there another way to locate touchdesigner.exe via version/build in Windows?
Ive used this since many years since I also needed to maintain many projects over many td versions. - it’s superhandy
Peeet
February 18, 2026, 9:12pm
4
There’s also a new tool by Daniel Molnar based off Lucas’ original tool:
1 Like
+1 ( just for general sanities sake)
These are great links but besides the point of my core question about the installer, I’ll check them out!
This did help me identify another way than filesystem lookups for identifying installed versions, via Windows Registry.
if os.path.exists(player_exe):
# Convert key from TouchDesigner.X.Y to TouchPlayer.X.Y
numeric = td_key.split('.', 1)[1] if '.' in td_key else td_key
player_key = f"TouchPlayer.{numeric}"
player_dict[player_key] = {
'install_path': install_path,
'executable': player_exe
}
return player_dict
def _query_windows_registry(self, product: str = "TouchDesigner") -> Dict[str, dict]:
"""Query Windows registry for TouchDesigner or TouchPlayer installations.
Primary: HKLM\\SOFTWARE\\Derivative\\<product> — version entries matched
to Path entries by substring. Fallback for any unmatched versions:
HKEY_CLASSES_ROOT\\<product>.<version>\\shell\\open\\command which stores
the executable path directly via file-association registration.
"""
try:
import winreg
except ImportError:
snaut
February 19, 2026, 9:05pm
8
Hi @cem_futuretense
we’ll add that as an option to the installer. The “TouchDesigner” path is intended to simplify updates on systems where only a single install of TouchDesigner is running and eventual startup scripts depend on a fixed filepath.
cheers
Markus
1 Like
Thanks Markus, I see both sides of it here!
For the people trying to make launch scripts here, this is my PowerShell version of what TD-Launcher-Plus does:
function Get-TdInstallsViaRegistryLookup {
$tdDict = @{}
$versions = @()
$paths = @{}
# -- Primary: HKLM path-based lookup --------------------------------
$hklmPath = "HKLM:SOFTWARE\Derivative\TouchDesigner"
if (Test-Path $hklmPath) {
$values = Get-ItemProperty $hklmPath
foreach ($name in $values.PSObject.Properties.Name) {
$value = $values.$name
if ($name -like 'Path*') {
# write-Info "Found registry path entry: $name = $value"
$paths[$name] = $value
}
elseif ($name -match '^\d{4}\.\d+$') {
# Write-Info "Found registry version entry: $name = $value"
$versions += $name
}
}
foreach ($version in $versions) {
$installPath = $null
foreach ($pathName in $paths.Keys) {
$pathValue = $paths[$pathName]
if ($pathValue -like "*$version*") {
$installPath = $pathValue
break
}
}
if ($installPath) {
$tdDict[$version] = $installPath
}
}
}
# -- Fallback: HKCR file-association lookup for unmatched versions ---
$resolvedVersions = $tdDict.Keys
$unmatchedVersions = $versions | Where-Object { $resolvedVersions -notcontains $_ }
foreach ($version in $unmatchedVersions) {
# $hkcrKeyPath = "HKCR:TouchDesigner.$version\shell\open\command" # Not in PSDrive
$hkcrKeyPath = "Registry::HKEY_CLASSES_ROOT\TouchDesigner.$version\shell\open\command"
if (Test-Path $hkcrKeyPath) {
# Write-Info "Found HKCR key for version ${version}: $($hkcrKey.PSPath)"
$commandVal = (Get-ItemProperty -Path $hkcrKeyPath | Select-Object -ExpandProperty '(default)' -ErrorAction SilentlyContinue)
if ($commandVal -and $commandVal -match '"([^"]+)"') {
$exePath = $Matches[1]
if (Test-Path $exePath) {
$installPath = Split-Path (Split-Path $exePath) -Parent
$tdDict[$version] = $installPath
}
}
}
}
# Sort dictionary by version keys alphabetically
$tdSortedDict = [ordered]@{}
foreach ($key in $tdDict.Keys | Sort-Object) {
$tdSortedDict[$key] = $tdDict[$key]
}
return $tdSortedDict
}
Creates a Dictionary of builds vs install paths.
{
"2023.12600": "C:\Program Files\Derivative\TouchDesigner.2023.12600",
...
}