Hint: Passing TC variables %N,%P,%P%N,etc, as input to PowerShell.ps1 and turning them now into the PS script variables

English support forum

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

Hint: Passing TC variables %N,%P,%P%N,etc, as input to PowerShell.ps1 and turning them now into the PS script variables

Post by *beb »

Recently, PowerShell is getting more and more use as my primary tool for different TC user commands.
The last thing I've been trying is to pass TC variables (such as %N, %P, %P%N, %S, etc) to a PowerShell .ps1 script as input parameters and then use them there again as variables now the PowerShell script's ones.
Here's the solution I've found so far [based on the $args array]:

PowerShell_test_TC_param_N_P_PN_PS_etc.ps1:

Code: Select all

$param = $args[0];"%N:       $param"
$param = $args[1];"%P:       $param"
$param = $args[2];"%P%N:     $param"
$param = $args[3];"%S:       $param"
$param = $args[4];"%P%S:     $param"
$param = $args[5];"[%P]%S#1: $param"
$param = $args[6];"[%P]%S#2: $param"
$param = $args[7];"[%P]%S#3: $param"
$param = $args[8];"[%P]%S#4: $param"
$param = $args[9];"[%P]%S#5: $param"
""
'the $args array at the whole:'
$args
pause
usercmd.ini:

Code: Select all

[em_tcps_test]
cmd=Powershell -ExecutionPolicy Bypass %commander_path%\PowerShell_test_TC_param_N_P_PN_PS_etc.ps1
param=""""%N""" """%P""" """%P%N""" """%S""" """%P%S""""
button:

Code: Select all

TOTALCMD#BAR#DATA
em_tcps_test

wcmicons.dll
PowerShell_test_TC_params

0
10028
In the example, we are passing five TC variables at once, namely %N, %P, %P%N, %P%S, %S where each of %N, %P, %P%N can be referred to individually by position as $args[0], $args[1], $args[2] respectively.
The %S-based group entries (with the list-like content depending on what was selected), if any, and if needed, can be caught individually by correspondent numbers of further $args[*] (here $args[3], $args[4], etc), and/or by other means for processing the PowerShell arrays.
Then the variables can be processed within a .ps1 script as needed.

Here's the example command output upon running where the file under the cursor is the script itself and some other random folder nearby has been selected:

Code: Select all

%N:       PowerShell_test_TC_param_N_P_PN_PS_etc.ps1
%P:       e:\TEST\Apps\TC\
%P%N:     e:\TEST\Apps\TC\PowerShell_test_TC_param_N_P_PN_PS_etc.ps1
%S:       various_tests
%P%S    : e:\TEST\Apps\TC\various_tests
[%P]%S#1:
[%P]%S#2:
[%P]%S#3:
[%P]%S#4:
[%P]%S#5:

the $args array at the whole:
PowerShell_test_TC_param_N_P_PN_PS_etc.ps1
e:\TEST\Apps\TC\
e:\TEST\Apps\TC\PowerShell_test_TC_param_N_P_PN_PS_etc.ps1
various_tests
e:\TEST\Apps\TC\various_tests
May someone else finds it useful as well.

Edit:
Initial [param=%N %P %P%N %S %P%S] string has been rewritten as [param=""""%N""" """%P""" """%P%N""" """%S""" """%P%S""""] to cope both the need of "quotation marks" for the names with spaces as long as the Total Commander and PowerShell parsing approaches.
Big thanks to u/Fla$her for the important remark.

NB

Explanation of the example PowerShell script:
The example script is harmless by design and does nothing more than just taking the current %N, %P, %P%N, %P%S, %S variables and displaying their current values (if any).
%N, %P, %P%N variables are predictable since always describe the file under the cursor in the active pane (its name, path, and both path/name), so the first three lines ($args[0..2]) of the script are enough to show that.
%P%S, %S variables are unpredictable as their values depend on what is selected in the active pane ($args[3..9] may show something or may show nothing)
In the end, for testing purposes, the script shows the $args array in full whether or not it's been embraced by the $args[0..9].
Note: As I now can see after all, as soon as the variables have been put in quotes, $args[5..9] become completely useless and normally won't ever return anything, so those strings could be omitted [on the contrary, if $args[5..9] are not empty, something goes wrong: see the screenshots below].
Last edited by beb on 2023-04-26, 23:46 UTC, edited 9 times in total.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
User avatar
Stefan2
Power Member
Power Member
Posts: 4281
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Hint: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *Stefan2 »

Is there a question somehow, or do you provide a solution?
A proper subject would help to answer this on its own ;-)







 
Fla$her
Power Member
Power Member
Posts: 2982
Joined: 2020-01-18, 04:03 UTC

Re: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *Fla$her »

beb wrote: 2023-04-26, 14:40 UTCparam=%N %P %P%N %P%S %S
%P should always be put in quotation marks.
Overquoting is evil! 👎
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: Hint: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variabl

Post by *beb »

Stefan2 wrote: 2023-04-26, 15:15 UTC A proper subject would help to answer this on its own ;-)
By the way, the subject field here on the board is pretty narrow so it ain't no easy to pick a title that is at the same time compact to fit the field and meaningful without being lost in translation, moreover, for the title that has been originally comparable to the one-stringer version of the "War and peace". Aside from this, a "hint" fairly suits there. Thank you for the hint! :D
Stefan2 wrote: 2023-04-26, 15:15 UTC Is there a question somehow, or do you provide a solution?
It's rather a kind of r/showerthoughts.
Once I meet a question*, then I find a solution.

The question originates from there:
beb wrote: 2023-04-13, 17:37 UTC ...As you would be able to see (via "write-host "%P%S"" output), "%P%S" would return a string that consists of the selected files' full names separated by the blank space(s).
beb wrote: 2023-04-13, 19:29 UTC Again, if pdfs names contain spaces %P%S output becomes practically useless since it ain't no easy and user-friendly way to split such a spacious string into meaningful parts (to extract separate file names in the end).
Therefore, it's better (much simpler) to use %L instead of %P%S here...
#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: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *beb »

Fla$her wrote: 2023-04-26, 15:34 UTC
beb wrote: 2023-04-26, 14:40 UTCparam=%N %P %P%N %P%S %S
%P should always be put in quotation marks.
"quotation marks" marks have been there but then I removed them since it crashed the command/script.
Now I need more time for a fully functional solution.
For the PowerShell, those ("quotation marks") should look there like this (but only for the first two members (%N, and %P) so far!):

Code: Select all

param="""%N""" """"%P""""
Now the rest of the string either won't work properly or crash the command.
Thank you, I'm trying to fix that.

NB Thus, the command in its original version works only if the paths/names don't include spaces.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Fla$her
Power Member
Power Member
Posts: 2982
Joined: 2020-01-18, 04:03 UTC

Re: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *Fla$her »

beb wrote: 2023-04-26, 17:00 UTC For the PowerShell, those ("quotation marks") should look there like this (but only for the first two members (%N, and %P) so far!):

Code: Select all

param="""%N""" """"%P""""
You can also try this: "'%P'"
And why for %N? He has no problems with the auto-insertion of quotation marks.
Overquoting is evil! 👎
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *beb »

beb wrote: 2023-04-26, 17:00 UTC For the PowerShell, those ("quotation marks") should look there like this (but only for the first two members (%N, and %P) so far!):
This one version seemingly works as intended:

Code: Select all

param=""""%N""" """%P""" """%P%N""" """%S""" """%P%S""""
Explanation:
Each separate variable element should be put in its own tripled quotation marks pair (a triplet <"""> before, and a triplet <"""> after EACH VARIABLE), thus:

Code: Select all

"""%N"""

Code: Select all

"""%P"""

Code: Select all

"""%P%N"""

Code: Select all

"""%S"""

Code: Select all

"""%P%S"""
Then, the whole string should be put in common pair of quotation marks (a quote <"> before, and a quote <"> after the STRING OF VARIABLES), thus you can see a miraculously monstrous quadro-quote (<"""">) at the beginning and at the end of the whole string.
Last edited by beb on 2023-04-26, 23:52 UTC, edited 2 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

Re: Passing TC variables %N,%P,%P%N, etc, as input to PowerShell .ps1 and turning them now into the script variables

Post by *beb »

Fla$her wrote: 2023-04-26, 17:42 UTC And why for %N?
It just doesn't work if the filename itself includes spaces.
Compare command outputs (111 111.txt under the cursor):
[param=%N """%P""" %P%N %S %P%S]:
Image: https://i.imgur.com/GWkROjd.png (it's just a mess: 111 111 got split here and there and whatever)
vs
[param=""""%N""" """%P""" """%P%N""" """%S""" """%P%S""""]:
Image: https://i.imgur.com/tAY78d1.png (this looks humanly)

NB
[param=""""%N""" """%P""" """%P%N""" """%S""" """%P%S""""] (everything is selected):
Image: https://i.imgur.com/9mEl9sL.png (looks humanly too)
Last edited by beb on 2023-04-26, 23:53 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
ZoSTeR
Power Member
Power Member
Posts: 1049
Joined: 2004-07-29, 11:00 UTC

Re: Hint: Passing TC variables %N,%P,%P%N,etc, as input to PowerShell.ps1 and turning them now into the PS script variab

Post by *ZoSTeR »

 
I've been using this pattern to call PS-Scripts:
Command: PowerShell.exe
Parameters:

Code: Select all

-Executionpolicy remotesigned -Command "&{&'D:\PS-Scripts\SomeScript' -MyParameter '%P%O.%E'}"
or with environment-variables:

Code: Select all

-ExecutionPolicy remotesigned -Command "&{&"""${env:COMMANDER_PATH}\Tools\PowerShell\SomeScript.ps1""" -MyParameter '%L'}"

I don't think you can fix the "%S" problem, because TC itself is inserting unescaped double-quotes.

Just use a list-file like so:

Button:

Code: Select all

powershell.exe
-NoExit -ExecutionPolicy remotesigned -Command "& {& """${env:COMMANDER_PATH}\PS_Scripts\SomeScript.ps1""" -ListFile '%UL'}"
Script:

Code: Select all

param(
    [string]$ListFile
)

$files = Get-Content -LiteralPath $ListFile
foreach ($file in $files)
{
    echo $file
}
User avatar
beb
Power Member
Power Member
Posts: 579
Joined: 2009-09-20, 08:03 UTC
Location: Odesa, Ukraine

Re: Hint: Passing TC variables %N,%P,%P%N,etc, as input to PowerShell.ps1 and turning them now into the PS script variab

Post by *beb »

ZoSTeR wrote: 2023-04-26, 22:00 UTC I don't think you can fix the "%S" problem, because TC itself is inserting unescaped double-quotes.
Now I don't think so either.
And yes, %L-type variables are very useful here instead of the %S-type ones.

Here's my example how I came to the same understanding:
beb wrote: 2023-04-13, 19:29 UTC ...The below command would process any selected files, including ones with spaces:

Code: Select all

[em_pdf_selected]
cmd=Powershell -ExecutionPolicy Bypass; set bin -value "C:\CMYK.exe";
param=write-host "%L";Get-Content "%L"|ForEach-Object -process {write-host $('"""'+$_+'"""');& $bin $('"""'+$_+'"""')};pause
NB "write-host..." and "pause" parts don't do actual work there, just allow you to see what data you are dealing with and understand where to go to. As soon as the command passes the workability exam we would wipe them out.
It's just a thing of how TC usercmd.ini syntax represents itself as ridiculously outdated here.
The main advantage of the %L-type is that it splits the selection list into separate strings so I can easily get it back as separate items line by line (Get-Content "%L") and process each item individually not caring if it contains spaces as long as the issue is not in spaces within the item, but in spaces between the items which contain spaces altogether.
I'm just very sorry for such complex wording, but that's just c'est la vie.
By the way, if it were a variable like %L-type that just doesn't write anything into %TEMP% (i.e., e.g. keeps it in RAM) that would be a comfortable solution for the issue.
And maybe the time comes when Mr. Ghisler will put some more attention for making TC more friendly to the tools like PowerShell, which is much more powerful and flexible than the honorable cmd for the users' needs within the TC (and I dare to expect that the related requests would become a bit more popular with time).

Thank you very much for the input and for sharing your experience!.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Fla$her
Power Member
Power Member
Posts: 2982
Joined: 2020-01-18, 04:03 UTC

Re: Hint: Passing TC variables %N,%P,%P%N,etc, as input to PowerShell.ps1 and turning them now into the PS script variab

Post by *Fla$her »

beb wrote: 2023-04-26, 23:04 UTCAnd maybe the time comes when Mr. Ghisler will put some more attention for making TC more friendly to the tools like PowerShell, which is much more powerful and flexible than the honorable cmd for the users' needs within the TC
You can use VBScript, JScript, AutoIt, AHK, gentee, LangMF, Kixtart, etc., which not only do not have such problems with parameters, but also start much faster, work portably on older Windows versions and do not annoy the console window.

And it's better to take %WL instead of %L to support unicode characters.
Overquoting is evil! 👎
Post Reply