It is currently January 23rd, 2022, 5:57 pm

## Passing Path with spaces to RunCommand

Help with creating, editing & fixing problems with skins
RedEye45
Posts: 3
Joined: June 29th, 2021, 5:18 am

### Passing Path with spaces to RunCommand

Hi, I am trying to use a PowerShell script to extract icons from a executable. The script takes in three arguments: Path to Exe, Output Dir, and Output Name. My issue is that I need to pass a path that contains spaces e.g: C:\Program Files\Blender Foundation\Blender 2.93\blender.exe. But PowerShell interprets the path as multiple arguments, messing up the script.

This is the PowerShell script (taken from this post https://forum.rainmeter.net/viewtopic.php?t=32404:

Code: Select all

@echo off
setlocal

set "exe_in=%~1"
set "out_dir=."
set "out_nam=%~3"

echo "ExecutablePath : %exe_in%"
echo "OutputPath : %out_dir%"
echo "OutputName : %out_nam%"

if not "%~2"=="" 2>NUL pushd "%~2" && ( call set "out_dir=%%CD%%" & popd )
set "ico_out=%out_dir%\%out_nam%.ico"

set "psCommand1="Remove-Item(\"%ico_out%\")""

[Drawing.Icon]::ExtractAssociatedIcon(\"%exe_in%\").ToBitmap().Save(\"%ico_out%\")""

set "psCommand3="[System.Diagnostics.FileVersionInfo]::GetVersionInfo(\"%exe_in%\").FileDescription""

powershell -noprofile -noninteractive %psCommand1%

powershell -noprofile -noninteractive %psCommand2%

powershell -noprofile -noninteractive %psCommand3%

This is the RunCommand Measure.

Code: Select all

[MeasureGetIcon0]
Measure=Plugin
Plugin=RunCommand
Program =#@#Scripts\bat\get-name-and-icon.bat
Parameter="#Path0#" "#@#Icons" "Icon0"
UpdateDivider=-1
OutputFile=Command0.txt
OutputType=ANSI
DynamicVariables=1
Substitute="#CRLF#":""
FinishAction=[!Log "GetIconFinished #Path0#"][!Update][!Redraw]

The Powershell script outputs this:

Code: Select all

"ExecutablePath : C:\Program"
"OutputPath : ."
"OutputName : Foundation\Blender"

Remove-Item : Cannot find path 'C:\Users\ahsan\OneDrive\Documents\Rainmeter\Skins\Rainmeter
Dock\Foundation\Blender.ico' because it does not exist.

I tried surrounding all the parameters in double quotes and some other suggestions:
• Parameter=""#Path0#" "#@#Icons" "Icon0""
• Parameter="\"#Path0#\" \"#@#Icons\" \"Icon0\""
• Parameter="\'#Path0#\' \'#@#Icons\' \'Icon0\'"
But none of these worked.

I even tried this (The original author of the script used it in this way):

Code: Select all

[MeasureGetIcon0]
Measure=Plugin
Plugin=RunCommand
Parameter=#@#Scripts\bat\get-name-and-icon.bat "#Path0#" "#@#Icons" "Icon0"
OutputType=ANSI
OutputFile=Command0.txt
UpdateDivider=-1
DynamicVariables=1
Substitute="#CRLF#":""
FinishAction=[!Log "GetIconFinished #Path0#"][!Update][!Redraw]

While this works for the original author's example skin, it doesn't work for me even though I have the exact same directory structure. For me, it outputs a single

Code: Select all

'
and doesn't extract any icon at all.

Been stuck on this for an entire day. Would really appreciate if anyone can help .
death.crafter
Rainmeter Sage
Posts: 1294
Joined: April 24th, 2021, 8:13 pm

### Re: Passing Path with spaces to RunCommand

RedEye45 wrote: June 29th, 2021, 5:51 am
Actually, I would suggest using PowershellRM. Here is the script:
Now in Rainmeter, you can execute an action like:
PowershellRM documentation: https://khanhas.gitbook.io/powershellrm/

But ofc you can change the script for your own purposes. I just generalized it.

Here is the example skin:
IconExtractor_1.00.rmskin
If something doesn't work out right or you get errors feel free to reply.

Hope this helps.

Regards,
death.crafter
You do not have the required permissions to view the files attached to this post.
from the Realm of Death
RedEye45
Posts: 3
Joined: June 29th, 2021, 5:18 am

### Re: Passing Path with spaces to RunCommand

death.crafter wrote: June 29th, 2021, 7:47 am
Thanks a lot for the help. I have got it working for a extracting a single Icon. But I am working on a sort of dock, which has multiple icons (total number can be changed by the user), which I am updating at OnRefreshAction. So I tried incorporating a loop in the script you gave me. I don't really have any experience with PowerShell so I did a bit of Googling and just stuck in a for-loop and a bunch of -join functions.
But I get this error:
I'm not sure why exactly it's complaining about concurrency. Being used to regular C and C# loops, I thought this might run serially too. Anyways, is there a better way to call the extract function multiple times, each operating on a different path?
Last edited by RedEye45 on June 29th, 2021, 12:33 pm, edited 2 times in total.
death.crafter
Rainmeter Sage
Posts: 1294
Joined: April 24th, 2021, 8:13 pm

### Re: Passing Path with spaces to RunCommand

RedEye45 wrote: June 29th, 2021, 9:34 am
Check this if works and notice the comments.

Of Option 1 and 2 you can use either one, based on your requirements.

If you face some errors or don't understand something, I am here, :P
Still I would like to see how your skin works internally, so if you can, post an rmskin or zip of the skin folder here.

Regards,
death.crafter
from the Realm of Death
Yincognito
Rainmeter Sage
Posts: 4132
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

### Re: Passing Path with spaces to RunCommand

RedEye45 wrote: June 29th, 2021, 5:51 am Hi, I am trying to use a PowerShell script to extract icons from a executable. The script takes in three arguments: Path to Exe, Output Dir, and Output Name. My issue is that I need to pass a path that contains spaces e.g: C:\Program Files\Blender Foundation\Blender 2.93\blender.exe. But PowerShell interprets the path as multiple arguments, messing up the script.
Actually, it only gives the error if the icon file doesn't yet exist (i.e. you're at first execution and the icon has not yet been saved). After the 1st execution, no error comes up. The original batch file didn't check if the icon existed before trying to delete it (Remove-Item).

But then, the question is ... why would one need a batch file to run a powershell script? You can simply do...

Skin:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

---Measures---

[MeasureGetIcon0]
Measure=Plugin
Plugin=RunCommand
Program=powershell
Parameter=-noprofile -noninteractive "#@#Scripts\powershell\get-name-and-icon.ps1" '#Path0#' '#@#Icons\Icon0.ico'
UpdateDivider=-1
OutputFile=Command0.txt
OutputType=ANSI
DynamicVariables=1
Substitute="#CRLF#":""
FinishAction=[!Log "GetIconFinished #Path0#"][!UpdateMeter *][!Redraw]

---Meters---

[MeterTest]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
FontSize=16
AntiAlias=1
MeasureName=MeasureGetIcon0
Text="Output:"
LeftMouseUpAction=[!CommandMeasure MeasureGetIcon0 "Run"]
UpdateDivider=-1
DynamicVariables=1

[MeterImage]
Meter=Image
X=5R
ImageName=#@#Icons\Icon0.ico
UpdateDivider=-1
DynamicVariables=1

PS Script (located at #@#Scripts\powershell\get-name-and-icon.ps1):

Code: Select all

if (Test-Path $args[1]) {Remove-Item$args[1]}
[void][Reflection.Assembly]::LoadWithPartialName('System.Drawing');[Drawing.Icon]::ExtractAssociatedIcon($args[0]).ToBitmap().Save($args[1])
[System.Diagnostics.FileVersionInfo]::GetVersionInfo(\$args[0]).FileDescription

It's basically about avoiding the need for a .bat file - much shorter and clearer codes all around. Only 2 parameters (the full path to the EXE and the ICO) are required as the PS script's parameters, they are enclosed between apostrophes (i.e. ') and if by any chance you have other apostrophes in your path, you can escape them by repeating the apostrophe, e.g. 'C:\Program Files\Apos'trophe' will become 'C:\Program Files\Apos''trophe'.

As for the automation process, I see death.crafter already took care of that. I just wanted to show that the original process can be both corrected and simplified.
RedEye45
Posts: 3
Joined: June 29th, 2021, 5:18 am

### Re: Passing Path with spaces to RunCommand

I have got it to work just fine using a mix of both the suggestions by you guys. Thanks a LOT for the help. Really appreciate it .
Yincognito
Rainmeter Sage
Posts: 4132
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

### Re: Passing Path with spaces to RunCommand

RedEye45 wrote: June 29th, 2021, 3:58 pm I have got it to work just fine using a mix of both the suggestions by you guys. Thanks a LOT for the help. Really appreciate it .
Excellent then. Death.crafter did most of the work though - my suggestion would have probably needed either a FOR in Powershell / some tweaking to accept a list of parameters through some wildcard system, or just run those RunCommands for each meter you wanted to have an associated icon in native Rainmeter code if you found the exclusive PowerShell approach too complex.

For the latter, a simplified version, in case someone else needs it as a base for future work (I kept the Metadata and the original authorship of StArL0rd84, as the modifications are minor, really - just simplification and some Default.ico to avoid errors if the icons don't exist yet):
Icon Extractor_3.0.0.rmskin
Icon Extractor.jpg
P.S. Using this would probably (not sure, as I have full rights already) require permission to directly run PowerShell scripts on the computer, by running PowerShell as an Administrator and entering set-executionpolicy remotesigned into it. Of course, this assumes one knows what's safe or not for him and some reasonable common sense when dealing with unknown scripts.
You do not have the required permissions to view the files attached to this post.