The thing is, a common user has no option for that, nor did I.
So I became interested in finding a way to do it easily, quickly, and steadily safely.
After a chain of experiments that finally proved to be a success (from my point of view), I came to a solution that fitted my needs.
So hereby I share my solution, and this is the primary point of my message.
Feel free to test it, use it, modify it, and do whatever you want.
Total Commander installer does not provide its common users with an explicit and unconditional option to install a clean copy of the program so far.
As soon as a valid existing configuration [ini] of the previously installed copy could be found [via the resident registry data] the installer (both in GUI/CLI modes) will always take the content from there.
I'm afraid that behavior is by design (to say a feature, not a bug).
Therefore, I made a script that overrides this behavior.
Caution:
I can do the custom installer repack but I am not interested in it and do not want to.
(see: https://www.ghisler.ch/wiki/index.php?title=Custom_installer)
Thus, had such a discussion emerged here I myself would contribute nothing to it (even though it may be useful for someone else).
Main notes:
[0] If Mr ghisler(Author) decides to fix the said installer behavior (by implementing corresponding explicit installer's options, e.g. for the CLI mode N or P0 - Not to use/imPort any data from the previous installations), the main script still may remain actual for those who'd want to have a bit customized .ini from the very start. And the informer subscript (which can be run standalone) can be helpful to give a user a piece of information on what data their Total Commander keeps in the AppData/Registry that they have no idea about.
[1] The entire installation time from start to finish on my ancient machines is within 0.2...0.4 seconds (200...400 milliseconds).
Not that long, I suppose.
[2] The Total Commander installer command in the script is as follows:
$installer /A1H1L1M0G0D0U0FRI0'".\"' $installFolder
where the script variables:
Code: Select all
$installer : installer variable (e.g., "tcmd1103x32_64.exe", the freshest one currently)
$installFolder : install folder variable (under the naming template: "$env:Temp\TC_yyyyMMdd_HHmmss\totalcmd")
(see https://www.ghisler.ch/wiki/index.php?title=Installer#Command_line_parameters)
Code: Select all
A1 : automatic
H1 : hidden
L1 : English language
M0 : no other languages
G0 : no Windows menu entries
D0 : no Desktop shortcuts
U0 : no updates to anything
F : force a normal installation (ignore previous installation folders)
R : no registry uninstall-related records
I0 : no registry .ini location-related records
".\" : place configuration files (.ini) in the program folder
(the .ini file will be in the UTF-16 LE BOM encoding)
Code: Select all
[Configuration]
UseIniInProgramDir=7
DirUsageLocation=%commander_path%\Temp
IgnoreListFile=%commander_path%\Temp\tcignore.txt
ListName=%commander_path%\Temp\ftplist.txt
LogFile=%commander_path%\Temp\totalcmd.log
TabDir=%commander_path%\Temp
ThumbsLocation=%commander_path%\Temp
TreeFileLocation=%commander_path%\Temp\treeinfo%D%.wc
StartupScreen=0
UseRightButton=0
FirstTime=0
FirstTimeIconLib=0
UseNewDefFont=1
[4] The script has been tested on Windows PowerShell 5.1 and on cross-platform PowerShell 7.4+
Other notes
[5] The script implies optional usage of the informer subscript [tcmd_cli_setup_reporter_*.ps1] (which will be explained later, if needed).
[6] By default, the script is supposed to get launched from a subfolder of a directory where the Total Commander installer(s) reside.
Otherwise, you may need to type another path to the installer there, like $env:path +=";y:\our\installer\directory"
[7] The script uses "TC_yyyyMMdd_HHmmss/totalcmd" naming template for the target install folder within the Temp directory.
This grants no other copies (if any) of Total Commander could be affected by the new installation, even those installed with the script.
As an addition to that, the script still won't use the same folder even then:
If you manage to run the script more than once within the same second the installation will quit, while you will be offered to try again later (until the next second ticks).
[6] By default, the script is supposed to get launched from a subfolder of a directory where the Total Commander installer(s) reside.
Otherwise, you may need to type another path to the installer there, like $env:path +=";y:\our\installer\directory"
[7] The script uses "TC_yyyyMMdd_HHmmss/totalcmd" naming template for the target install folder within the Temp directory.
This grants no other copies (if any) of Total Commander could be affected by the new installation, even those installed with the script.
As an addition to that, the script still won't use the same folder even then:
If you manage to run the script more than once within the same second the installation will quit, while you will be offered to try again later (until the next second ticks).
Scenario 1
conditions:
- bare main script (without informer subscript).
- no other Total Commander copies have been detected (no valid data leading to such copies present).
(either, this is a primary installation, or previous installation(s) is/are truly portable).
screen 1.1
Image: https://i.imgur.com/ub5Qh4Q.png
- bare main script (without informer subscript).
- no other Total Commander copies have been detected (no valid data leading to such copies present).
(either, this is a primary installation, or previous installation(s) is/are truly portable).
screen 1.1
Image: https://i.imgur.com/ub5Qh4Q.png
Scenario 2
conditions:
- main script with a brief informer subscript.
- no other Total Commander copies have been detected (as above).
screen 2.1
Image: https://i.imgur.com/vm4baCO.png
- main script with a brief informer subscript.
- no other Total Commander copies have been detected (as above).
screen 2.1
Image: https://i.imgur.com/vm4baCO.png
Scenario 3
conditions:
- main script with a brief informer subscript.
- valid data of a previous Total Commander copy have been detected.
screen 3.1
Image: https://i.imgur.com/U8NKqk2.png
screen 3.2
Image: https://i.imgur.com/H06pi5U.png
screen 3.3
Image: https://i.imgur.com/lTQFuJY.png
screen 3.4
Image: https://i.imgur.com/M6HlDps.png
screen 3.5
Image: https://i.imgur.com/hfj4Fln.png
screen 3.6
Image: https://i.imgur.com/rDgLnOs.png
screen 3.7
Image: https://i.imgur.com/YfOMcwg.png
screen 3.8
Image: https://i.imgur.com/JUbeEXf.png
- main script with a brief informer subscript.
- valid data of a previous Total Commander copy have been detected.
screen 3.1
Image: https://i.imgur.com/U8NKqk2.png
screen 3.2
Image: https://i.imgur.com/H06pi5U.png
screen 3.3
Image: https://i.imgur.com/lTQFuJY.png
screen 3.4
Image: https://i.imgur.com/M6HlDps.png
screen 3.5
Image: https://i.imgur.com/hfj4Fln.png
screen 3.6
Image: https://i.imgur.com/rDgLnOs.png
screen 3.7
Image: https://i.imgur.com/YfOMcwg.png
screen 3.8
Image: https://i.imgur.com/JUbeEXf.png
Still, as you can see, the Total Commander installer is dragging a whole lot of old data into my new .ini, which I didn't ask it to do, even though it (the installer) is unable to process all the data properly.
The script itself:
tcmd_cli_installer_v1.ps1
Code: Select all
[Diagnostics.Stopwatch]::StartNew()|Tee -var lap|Out-null
[Text.Encoding]::GetEncoding('Unicode')|Tee -var encoding|Out-null
Get-Date -format "yyyyMMdd_HHmmss"|Tee -var stamp|Out-null
.\tcmd_cli_setup_reporter_brief.ps1
#.\tcmd_cli_setup_reporter_verbose.ps1
$env:path +=";$($pwd|split-path)"
$installer = 'tcmd1103x32_64.exe'
$installFolder = $env:temp+'\TC_'+$stamp+'\totalcmd'
$ini = $installFolder+'\wincmd.ini'
""
if ($installFolder|Test-path) {
Write-Host 'CAUTION:' -f DarkYellow
Write-Host -f Yellow '$installFolder already exists'
Write-Host -f Yellow '$installer is quitting...'
Write-Host -f Yellow 'Note: give it another try in a while.'
}
else {
Write-Host -f Yellow 'installation : in progress...'
&{$PSNativeCommandArgumentPassing = 'Legacy'
& $installer /A1H1L1M0G0D0U0FRI0'".\"' $installFolder
}
""
Write-Host -f Cyan -no '$installer : '
Write-Host -f Blue $installer
Write-Host -f Cyan -no '$installFolder : '
Write-Host -f Blue $installFolder
Write-Host -f Cyan -no '$ini expected : '
Write-Host -f Blue $ini
""
$installation = Get-Process $($installer.split("."))[0]
if ($installation) {
Write-Host -f Yellow -no '$installer : '
Write-Host -f Blue -no $installation.Name
Write-Host -f Yellow ' is running...'}
Wait-Process $installation -EA Silent
Write-Host -f Yellow -no ' '
Write-Host -f Yellow -no 'checking for the '
Write-Host -f Blue -no '$ini '
Write-Host -f Yellow -no 'in the '
Write-Host -f Blue -no '$installFolder'
Write-Host -f Yellow -no '...'
""
while (-not ($ini|Test-Path)) {}
function ifLocked ($ini) {
try {
[IO.File]::OpenWrite($ini).Close();$false} catch {$true}
}
while ((ifLocked $ini) -ne $false) {}
$config = (@"
[Configuration]
UseIniInProgramDir=7
DirUsageLocation=%commander_path%\Temp
IgnoreListFile=%commander_path%\Temp\tcignore.txt
ListName=%commander_path%\Temp\ftplist.txt
LogFile=%commander_path%\Temp\totalcmd.log
TabDir=%commander_path%\Temp
ThumbsLocation=%commander_path%\Temp
TreeFileLocation=%commander_path%\Temp\treeinfo%D%.wc
StartupScreen=0
UseRightButton=0
FirstTime=0
FirstTimeIconLib=0
UseNewDefFont=1
"@)
""
if ($ini|Test-Path) {
Write-Host 'ATTENTION' -f DarkYellow
Write-Host -f DarkRed '$ini found with the following resident content:'
[IO.File]::ReadAllText($ini)}
else {
Write-Host 'ATTENTION' -f DarkYellow
Write-Host -f DarkRed '$ini not found; creating one...'}
New-Item $ini -type file -force > $null
""
Write-Host -f Yellow 'customization : in progress...'
[IO.File]::WriteAllLines($ini,$config,$encoding)
""
Write-Host 'INFORMATION' -f DarkYellow
Write-Host -f Green 'resulting $ini content:'
[IO.File]::ReadAllText($ini)|Out-host
}
""
.\tcmd_cli_setup_reporter_brief.ps1
#.\tcmd_cli_setup_reporter_verbose.ps1
""
$lap.Stop()
Write-Host -f Cyan ("Elapsed time : {0:ss}.{0:fff}" -f $lap.Elapsed) -no;" (script v1)"
""
pause
tcmd_cli_setup_reporter_brief.ps1
Code: Select all
$ghislerAppData = @("$env:AppData\Ghisler","$env:LocalAppData\Ghisler")
$ghislerRegistry = [ordered]@{
"HKCU:\SOFTWARE\Ghisler" ="HKCU:\SOFTWARE\GhislerBackup"
"HKLM:\SOFTWARE\Ghisler" ="HKLM:\SOFTWARE\GhislerBackup"
"HKLM:\SOFTWARE\WOW6432Node\Ghisler"="HKLM:\SOFTWARE\WOW6432Node\GhislerBackup"}
$max = -($ghislerAppData+$ghislerRegistry|Measure -Maximum -Property Length).Maximum
# research AppData
Write-Host -f Cyan '$AppData : ' -no
Write-Host -f Yellow 'checking for resident data...'
$ghislerAppData|foreach {
if (-not ($PSitem|Test-Path)) {
"{0,$max}" -f $PSitem|Tee -var noData|Out-null
Write-Host -f DarkGray $noData -no;' : does not exist; no action required'
}
else {
# report AppData
"{0,$max}" -f $PSitem|Tee -var Data|Out-null
Write-Host -f DarkRed $Data -no
Write-Host -f Yellow ' : contains data!'
$entry = Get-ChildItem $PSitem -recurse
foreach ($item in $entry) {
"{0,$max}" -f $item.FullName|Tee -var dataItem|Out-null
Write-Host -f DarkMag $dataItem}
}}
# research Registry
Write-Host -f Cyan '$Registry : ' -no
Write-Host -f Yellow 'checking for resident data...'
foreach ($key in $ghislerRegistry.keys) {
"{0,$max}" -f $key|Tee -var keyOut|Out-null
if (-not ($key|Test-Path)) {
Write-Host $keyOut -f DarkGray -no;' : does not exist; no action required'}
else {
Write-Host $keyOut -f Red -no
Write-Host -f Yellow ' : contains data!'
Get-ChildItem $key -recurse |foreach {
$regItem = $PSitem.toString()
$regItem = $regItem -replace 'HKEY.*USER\\','HKCU:' -replace 'HKEY.*MACHINE\\','HKLM:'
$regValues = @()
(Get-ItemProperty $regItem).PSobject.Properties|Where Name -notin PSPath,PSProvider,PSDrive,PSParentPath|Select Name,Value|
foreach {
$keyName = $_.name
$keyValue = $_.value
if ( $keyName -eq 'PSChildName') {
$subKey = $key + '\' + $keyValue}
else {
$regValues += "{0,-11} = {1}" -f $keyName, $keyValue}
}
Write-Host -f Red $subKey
$regValues|Sort-Object|foreach {
Write-Host -f Magenta $_
}}}}
if (-not $MyInvocation.PSCommandPath) {pause}
Edit 2024-03-15: initial .ini content update.
Edit 2024-03-25: initial .ini content update.