Page 1 of 1

Putting code output into a variable for string matching

Posted: 06 Dec 2022 15:56
by Quisquose
I need to be able to distinguish between two command line windows based on the text color that they use.

I found some code online that does this, but I have very limited experience with command line stuff and this particular code example is utterly impenetrable to me.

Code: Select all

@(Set/P "=The color is currently set to "<NUL&For /F %%# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"')Do @Set/P=%%#<NUL)&Echo(&Pause

I've seen other code examples where the variable was clearly identifiable. I could then compare that variable against some strings of my choosing and then take the necessary action based on various matches. But in this example I don't even know where the variable is!

How can I put the output of the code above (only the 2 character hex value, not the preamble text) into a variable, and then take one action if the variable matches 0B and another action if the variable matches 0F?

I intend to run this from an alias (doskey) so that I can just type the command and have the correct action taken based on the text color of the current console.

I appreciate any and all help. Thanks.

Re: Putting code output into a variable for string matching

Posted: 06 Dec 2022 17:26
by ShadowThief
It's much easier to read the code when it isn't all on one line.

Code: Select all

@(
	Set/P "=The color is currently set to "<NUL
	For /F %%# In ('
		^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP 
			"$Console=(Get-Host).UI.RawUI;
			Switch($Console.BackgroundColor,$Console.ForegroundColor){
				'Black'{'0'}
				'DarkBlue'{'1'}
				'DarkGreen'{'2'}
				'DarkCyan'{'3'}
				'DarkRed'{'4'}
				'DarkMagenta'{'5'}
				'DarkYellow'{'6'}
				'Gray'{'7'}
				'DarkGray'{'8'}
				'Blue'{'9'}
				'Green'{'A'}
				'Cyan'{'B'}
				'Red'{'C'}
				'Magenta'{'D'}
				'Yellow'{'E'}
				'White'{'F'}
			}" 2^>NUL^"'
	) Do (
		@Set/P=%%#<NUL
	)
)
Echo(
Pause
The main bit of the code is a powershell command that runs

Code: Select all

(Get-Host).UI.RawUI
and then returns values based on the values of ForegroundColor and BackgroundColor. For reference, when I run the first bit by itself, I get
ForegroundColor : Gray
BackgroundColor : Black
CursorPosition : 0,4
WindowPosition : 0,0
CursorSize : 25
BufferSize : 120,30
WindowSize : 120,30
MaxWindowSize : 120,30
MaxPhysicalWindowSize : 3424,84
KeyAvailable : True
WindowTitle : Command Prompt - powershell -NoP -Command "(Get-Host).UI.RawUI"
From there, a switch statement is used to replace the names of the colors with their equivalent hex codes from the color command. Since all of this is done in a for loop, the output of the powershell command gets stored in the for loop variable, which is %%#.

Re: Putting code output into a variable for string matching

Posted: 07 Dec 2022 02:41
by Quisquose
Thank you for your reply.

I did initially assume that %%# was the variable (given its position within the output) but I couldn't even get it to echo its contents on screen, nevermind do anything else with it.

How would I store the contents of %%# into my own named variable? I just want to be able to use something like

Code: Select all

if "%MyVar%" ==  "0B"
so that I can take different actions based upon whether the variable contents matches my string or not. But any commands that I put after the detect color code just get ignored (even after I've removed the pause command).

I tried adding

Code: Select all

SET MyVar=%%#
but when I check MyVar it contains nothing. If I try to use %%# directly, it's the same issue.

Thanks for cleaning up the script to make it more legible, but it no longer seems to work. I now get an error message. This doesn't occur when using the squashed up single-line version

Code: Select all

{ was unexpected at this time.
Apologies for my noobness.

Re: Putting code output into a variable for string matching

Posted: 07 Dec 2022 04:52
by ShadowThief
Correct; the code doesn't work if it stops being all on one line because of how the powershell is being executed. I only split it up to make it easier to read, I didn't add line continuation characters to make it keep working.

If you want to store the output of the powershell command in a variable, you can remove the set /p commands and everything outside of the @() bit. Since the background color and foreground colors are reported separately, you'll need to use delayed expansion to combine the two.

Code: Select all

@echo off
setlocal enabledelayedexpansion
For /F %%# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"') Do set "myVar=!myVar!%%#"
if "!myVar!"=="0B" (
    echo Light aqua is... certainly a choice...
)

Re: Putting code output into a variable for string matching

Posted: 07 Dec 2022 12:50
by Quisquose
Wow, thank you so much for this! It works like a charm, and I've now got it doing exactly what I want.

I would have never been able to figure this out for myself.

By the way, I'm not actually using Light Aqua - lol. I'm running a specific console session via a Start Menu shortcut (for which I've manually set my collection of preferred colors on the Color tab of the shortcut's Properties). So none of the colors are the same as the defaults (except for black and white).

Thanks again for your invaluable help.