PowerShell: adding|removing|saving Total Commander license key to|from the Windows Registry

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Hacker, petermad, Stefan2, white

Post Reply
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

PowerShell: adding|removing|saving Total Commander license key to|from the Windows Registry

Post by *beb »

tckey_registry_keyfile_zipArchive_inlineByteArray.ps1

Code: Select all

# tckey_registry_keyfile_zipArchive_inlineByteArray.ps1 v0.5 2025-03-09
# https://ghisler.ch/board/viewtopic.php?t=84672
# classic license keyfile
$keyLicense = 'wincmd.key'
# archived license keyfile
$zipLicense = @('tcmdkey.zip','*.zip')
# root paths where to look for the license keyfile
$root = @($env:commander_path,$PSScriptRoot)
# registry paths where license key can be stored
$hkcu = "HKCU:\SOFTWARE\Ghisler\Total Commander"
$hklm = "HKLM:\SOFTWARE\Ghisler\Total Commander"
$node = "HKLM:\SOFTWARE\WOW6432Node\Ghisler\Total Commander"
# registry path where license key to be stored
$path = $hkcu
# license key registry entry name
$name = 'key'

# get license key from classic license keyfile
$file = Get-ChildItem -path $root -filter $keyLicense -recurse -force | select -first 1
# read classic keyfile contents into a byte array
if ($file) {
$bytes = [byte[]][IO.File]::ReadAllBytes($file)
$keyfile = $file.FullName.substring($PSScriptRoot.length+1)
$info = 'the classic keyfile: {0}' -f $keyfile}

# get license key from archived classic license keyfile
if (-not ($bytes)) {
$file = Get-ChildItem -path $root -include $zipLicense -recurse -force | select -first 1
if ($file) {
# read archive, open classic keyfile as a stream, and copy its contents into a byte array
$zip = [IO.Compression.ZipFile]::OpenRead($file)
$stream = ($zip.Entries | Where {$_.Name -eq $keyLicense}).Open()
$memory = [IO.MemoryStream]::new()
$stream.CopyTo($memory)
$bytes = $memory.ToArray()
$stream.Dispose();$memory.Dispose();$zip.Dispose()
$archive = $file.FullName.substring($PSScriptRoot.length+1)
$info = 'the archived keyfile: {0}' -f $archive}}

# get license key directly in this script from the inline byte array of comma-separated decimal bytes
# note: to make it work replace $null below with the valid comma-separated decimal bytes (e.g. 0,10,100...)
if (-not ($bytes)) {$bytes = @(
$null
)
$info = 'the inline byte array of comma-separated decimal bytes'}

# get license key directly in this script from the inline byte array converted from the hex string
# note: to make it work replace $null below with the valid hex string (e.g. 00,0a,64...)
if (-not ($bytes)) {$hex = @'
$null
'@
# define $bytes depending on the PowerShell version 
if ($host.Version.Major -le 5) { # Windows PowerShell
$bytes = $hex.split(',').foreach{[byte]::Parse($_,'hex')}}
else { # Cross-Platform PowerShell
$bytes = [convert]::fromHexString($hex -replace ',')}
$info = 'the inline hex string'}

# if found, add the license key byte array to the registry
if ($bytes) {if (-not ($path|Test-Path)){New-Item -path $path -force}
Set-ItemProperty -path $path -name $name -value $bytes -type Binary -force # -WhatIf

# check how it went (displaying the first dozen of the license key bytes if found)
if ([BitConverter]::ToString((Get-ItemProperty -path $path).$name) -eq [BitConverter]::ToString($bytes)){
'TotalCommander license key'|Write-Host -f DarkCyan
'{0}...' -f ([BitConverter]::ToString($bytes).substring(0,35)).toLower()|Write-Host -f Cyan
'has been successfully added to the registry'|Write-Host -f DarkCyan
'from {0}' -f $info|Write-Host -f DarkCyan}}
else {
'No TotalCommander license keys have been found.'|Write-Host -f Yellow}

sleep -s 12
Explanations:

A. The way the script works by default

The script looks for a Total Commander license keyfile (named 'wincmd.key'):
- anywhere within the script root directory, and/or within the root path defined by the $env:commander_path variable (if the script started under the Total Commander running).
- within zip archives ('tcmdkey.zip', and any other '*.zip') anywhere within the script root directory, and/or within the root path defined by the $env:commander_path variable (same as above).

If the Total Commander license key is found:
- The script will read the license key as a byte array and put it into the registry

If several Total Commander license keys are found:
- The script will use only one of them (the first one found).

The script also can use a license key stored as a byte array directly in the script body.
- in the form of the decimal bytes (e.g. 0,10,100...)
- in the form of the hex string (i.e., exactly as the key seen in the registry, e.g. 00,0a,64...)

B. How does the script do that?

At first, it does some preparations (to say searches) behind the Get-ChildItem command(s).

Then it does the main job: reads the license as a byte array.
In the case of a standalone key file, it is as simple as that: [IO.File]::ReadAllBytes($file)
In the case of a packed keyfile, it is a bit complicated but still:
It will read the archive, open the classic keyfile from the archive as a stream, and copy its contents into a byte array.
If no standalone or packed keyfiles are there, the script can use the license key stored directly in its body as decimal bytes or hex string.

At the final stage, the script puts the license as a byte array into the registry behind the Set-ItemProperty command.

The script can also throw fancy colorful informative letters on your screen behind the Write-Host command(s).

C. for Customization?

Why not. A user can opt for a location to store the license key (HKLM, HKCU).
A user can modify/extend/contract arrays of places where the license keyfile is looked for, play with archive(s) and/or key file(s) naming(s), etc, regarding their specific preferences and approaches to such stuff.
Customization implies editing the script file manually in a text editor of your choice.

Notes
The script is tested under the cross-platform PowerShell (7+) and Windows PowerShell (5.1) on a Windows 10 Pro 64-bit machine.

Additional useful PowerShell scripts
tckey_registry_save.ps1 :: saves the Total Commander license key from the registry as a local file (in four formats).
tckey_registry_remove.ps1 :: removes the Total Commander license key from the registry.

History
2025-03-09 v0.5
[+] An option to add the license key into the registry directly from within the script body if the key is put there in the form of hex string (exactly as it is seen in the registry, e.g. 00,0a,64...).
2024-12-28 v0.3
[+] A message to inform a user of where the license has been retrieved from (a keyfile, and which one; an archive, and which one; an inline byte array, and which one).
2024-12-19 v0.1 script goes public.
Last edited by beb on 2025-03-16, 10:54 UTC, edited 11 times in total.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

PowerShell: removing TotalCommander license from the registry

Post by *beb »

tckey_remove_license_from_registry.ps1

Code: Select all

$path = @(
"HKCU:\SOFTWARE\Ghisler\Total Commander",
"HKLM:\SOFTWARE\Ghisler\Total Commander",
"HKLM:\SOFTWARE\WOW6432Node\Ghisler\Total Commander")
$name = 'key'

if (!(gp -path $path -name $name -EA:Silent)){
'There is no TotalCommander license in the registry.'|Write-Host -f Yellow -b DarkCyan}
if   (gp -path $path -name $name -EA:Silent) {
      rp -path $path -name $name -EA:Silent
if (!(gp -path $path -name $name -EA:Silent)){
'TotalCommander license has been successfully removed from the registry.'|Write-Host -f Yellow}}

sleep -s 7
gp is the standard alias for Get-ItemProperty.
rp is the standard alias for Remove-ItemProperty.
The script is pretty brief and self-explanatory.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
white
Power Member
Power Member
Posts: 5743
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: PowerShell: adding TotalCommander license to the registry

Post by *white »

Moderator message from: white » 2024-12-19, 09:26 UTC

Moved topic
» from Total Commander (English) to Plugins and addons: devel.+support (English)
User avatar
white
Power Member
Power Member
Posts: 5743
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: PowerShell: adding TotalCommander license to the registry

Post by *white »

2beb
Inspired by TC key.cmd?
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: PowerShell: adding TotalCommander license to the registry

Post by *beb »

2white

Yes, even though I didn't study it deeply and forgot about it, it turns out I keep an archive on my PC with a link to it and a text file with cmd script of version 1.02b, so apparently it did have a certain trace in my memory and made its input into my inspiration flow.
Thank you very much.

Edit2. message cleaned up.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: PowerShell: adding TotalCommander license to the registry

Post by *beb »

A little update has been rolling out.

a. regarding white's approach the version enumerating has been introduced.
b. as I figured out while working with the archived keyfile, creating the uncompressed memory stream, and transforming it toArray() could be dropped.

Edit:
c. as I figured out .b is was not always true, so those changes reverted.
Last edited by beb on 2024-12-28, 06:57 UTC, edited 1 time in total.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
MaxX
Power Member
Power Member
Posts: 1166
Joined: 2012-03-23, 18:15 UTC
Location: UA

Re: PowerShell: adding TotalCommander license to the registry

Post by *MaxX »

The same on .vbs

Code: Select all

If WScript.Arguments.Count > 0 Then
	Dim strFileIn

	strFileIn = ReadFile(WScript.Arguments.Item(0))

	strFileIn = "REGEDIT4" & Chr(10) & Chr(13) & Chr(10) & Chr(13) & _
			      "[HKEY_CURRENT_USER\Software\Ghisler\Total Commander]" & Chr(10) & Chr(13) & _
			       Chr(34) & "key" & Chr(34) & "=hex:" & strFileIn

	WriteFile WScript.Arguments.Item(0) & ".reg", strFileIn
End If
    
Function ReadFile(FileName)
    Dim Stream
    Dim byteFile
    Dim strHex
    Dim I
    
    Set Stream = CreateObject("ADODB.Stream")
    Stream.Type = 1 ' Binary
    Stream.Open
    Stream.LoadFromFile FileName
    byteFile = Stream.Read
    Stream.Close

    For I = 1 To LenB(byteFile)
        strHex = strHex & Hex(AscB(MidB(byteFile, I, 1)))
        
        If I < LenB(byteFile) Then
            strHex = strHex & ","
        End if
    Next
    
    ReadFile = strHex
End Function

Sub WriteFile(FileName, Content)
    Dim myFSO, WriteStuff

    Set myFSO = CreateObject("Scripting.FileSystemObject")
    Set WriteStuff = myFSO.OpenTextFile(FileName, 2, True)
    WriteStuff.WriteLine(Content)
    WriteStuff.Close
    SET WriteStuff = Nothing
    SET myFSO = Nothing
    
    MsgBox "'" & FileName & "' has been written.", 64, "Wincmd.key RegFile Maker"
End Sub
I have this now in my TCs test folder. It works for me when I need to put my WINCMD.KEY to registry. That is more useful than a key file when you need to test some betas in the same time.
Ukrainian Total Commander Translator. Feedback and discuss.
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: PowerShell: adding TotalCommander license to the registry

Post by *beb »

MaxX wrote: 2024-12-22, 13:21 UTC The same on .vbs...
A curious user is asking a question:
[Question]
- What is this .vbs script, how does it work, and what does it do?
Another user is answering:
[Answer]
- This is a Windows VBScript script.
- The given .vbs script has its modus operandi that implies it is provided with the input parameter, namely the Total Commander's license .key file.
-- One of the ways to do so (to give to the .vbs the input data it needs):
--- a user locates the .key file and drag-and-drops (or copy-pastes) the located .key file onto the .vbs file.
- The .vbs script processes the provided .key file and creates a .reg file next to itself.
- Later, a user can add the .reg file data into the registry (in a regular way to deal with the .reg files).


The PowerShell and the Windows VBScript scripts, and their function here are not 'the same.'

Of course, by design, both have to deal with the idea of reading the same source (.key file), and that's it.
Also, from the end user's point of view, they share the end result to a certain extent--an option to add the TotalCommander license to the registry.

VBScript (Microsoft Visual Basic Scripting Edition) is a programming language for scripting on Microsoft Windows using Component Object Model (COM) based on classic Visual Basic and Active Scripting, that is deprecated, will eventually be removed from Windows, and is not recommended.
PowerShell is a command-line shell and scripting language, that is open-source, cross-platform, built on .NET, commonly used for automating, and recommended.

It's good for a user to be well-informed and make the right choice of which approach fits their needs better within their environment.

Cheers.

Note:
Fellow users of this board, if interested, can find two kinds of the .vbs scripts (with some explanations from the authors) related to the 'TC-license-to-the-registry' question in a topic from 2010-2011: https://ghisler.ch/board/viewtopic.php?t=27098
The script that has been reposted here is namely one by CoolWater from there:
https://ghisler.ch/board/viewtopic.php?t=27098&p=207857#p207857
CoolWater wrote: 2010-08-09, 12:37 UTC 2Rein de Jong
since it is quite difficult to manage this task by hand, I've written a vb script for you:
If WScript.Arguments.Count > 0 Then...
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
MaxX
Power Member
Power Member
Posts: 1166
Joined: 2012-03-23, 18:15 UTC
Location: UA

Re: PowerShell: adding TotalCommander license to the registry

Post by *MaxX »

2beb
Well, I agree, they are not identical in the code. But are used for the same results.
AFAIK, my .vbs was taken long long time ago somewhere from this forum. Sorry, I can't remember the page or an author.
Ukrainian Total Commander Translator. Feedback and discuss.
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: PowerShell: adding TotalCommander license to the registry

Post by *beb »

2MaxX
It's ok. There is nothing wrong with sharing opinions and different approaches.
That's why we are here on this board.
This lets fellow users make reasonable decisions.
Thank you for your contribution.
Cheers.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: PowerShell: saving TotalCommander license key from the registry

Post by *beb »

PowerShell: save the Total Commander license key from the registry as a local file.

As soon as the Total Commander license key is found in the registry, it will be saved as a local file in four formats as follows:
  1. classic keyfile (.key file)
    naming: 'wincmd.key $TimeStamp $RegistrySourcePath.key'
  2. text file with the license key in a hex string format (exactly how the license key is seen in the Windows Registry)
    naming: 'wincmd.key $TimeStamp $RegistrySourcePath hex string.txt'
  3. text file with the license key in a comma-separated decimal bytes format
    naming: 'wincmd.key $TimeStamp $RegistrySourcePath decimal bytes.txt'
  4. regular Windows Registry .reg file
    naming: 'wincmd.key $TimeStamp $RegistrySourcePath.reg'
tckey_registry_save.ps1

Code: Select all

# tckey_registry_save.ps1 v0.1 2025-03-09
# https://ghisler.ch/board/viewtopic.php?t=84672
# root registry entries where license key can be stored
$registry = @(
"HKCU:\SOFTWARE\Ghisler\Total Commander",
"HKLM:\SOFTWARE\Ghisler\Total Commander",
"HKLM:\SOFTWARE\WOW6432Node\Ghisler\Total Commander")
# license key registry entry name
$name = 'key'
# timestamp
$stamp = Get-Date -format "yyyyMMdd"

# check if there are any Total Commander license key entries in the registry at all
if (!(Get-ItemProperty -path $registry -name $name -EA:Silent)){
'No Total Commander license keys have been found in the registry.'|Write-Host -f Yellow -b DarkCyan}

# process root registry entries one by one
foreach ($path in $registry) {
$path|Write-Host -f Green

if ($path|Test-Path) {if ((Get-Item $path).GetValue($name)) {

# define actual license key bytes
$bytes = Get-ItemProperty -path $path | select -ExpandProperty $name

# define registry source hive (where the license key is saved from)
if ($path -like '*WOW6432Node*') {$hive = 'NODE'}
else {$hive = $path.substring(0,4)}

# classic keyfile
$keyfile = [IO.Path]::combine($pwd,'wincmd.key '+$stamp+' '+$hive+'.key')
[IO.File]::WriteAllBytes($keyfile,$bytes)

# hex string (comma-separated hex bytes imitation)
$keyfile = [IO.Path]::combine($pwd,'wincmd.key '+$stamp+' '+$hive+' hex string.txt')
$hex = [BitConverter]::ToString($bytes).replace('-',',').toLower()
[IO.File]::WriteAllText($keyfile,$hex)

# comma-separated decimal bytes
$keyfile = [IO.Path]::combine($pwd,'wincmd.key '+$stamp+' '+$hive+' decimal bytes.txt')
$dec = ($bytes -join ',').ToString()
[IO.File]::WriteAllText($keyfile,$dec)

# regular reg file
$keyfile = [IO.Path]::combine($pwd,'wincmd.key '+$stamp+' '+$hive+'.reg')
if ($hive -eq 'HKCU') {$hkey = 'HKEY_CURRENT_USER\SOFTWARE'}
if ($hive -eq 'HKLM') {$hkey = 'HKEY_LOCAL_MACHINE\SOFTWARE'}
if ($hive -eq 'NODE') {$hkey = 'HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node'}
$reg = @"
Windows Registry Editor Version 5.00

[$hkey\Ghisler\Total Commander]
"key"=hex:$hex

"@ 
[IO.File]::WriteAllText($keyfile,$reg)

# display license key bytes partially
'decimal bytes : {0}...' -f $dec.substring(0,35)|Write-Host -f Cyan
'as hex string : {0}...' -f $hex.substring(0,35)|Write-Host -f Cyan

} else {'No TotalCommander license key here'|Write-Host -f DarkGray}}''}

sleep -s 12
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Post Reply